From 1e77cc66088a13b0d056117e154fef6dfb6ca9d1 Mon Sep 17 00:00:00 2001 From: Hermione Dadheech Date: Sun, 17 Nov 2024 23:47:47 +0530 Subject: [PATCH] feat:telemetry Integration in Vscode extension --- sidebar/sidebar.js | 1353 +++++++++++--------- src/extension.ts | 35 +- src/telemetry.ts | 88 ++ webviews/components/Config.svelte | 5 +- webviews/components/IntegrationTest.svelte | 9 + 5 files changed, 867 insertions(+), 623 deletions(-) create mode 100644 src/telemetry.ts diff --git a/sidebar/sidebar.js b/sidebar/sidebar.js index bab9e9a..9d0fdfe 100644 --- a/sidebar/sidebar.js +++ b/sidebar/sidebar.js @@ -48,151 +48,171 @@ let FilePath = ""; //cleanup required function formatDate(date) { - const day = String(date.getDate()).padStart(2, '0'); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const year = date.getFullYear(); - return `${day}/${month}/${year}`; +const day = String(date.getDate()).padStart(2, '0'); +const month = String(date.getMonth() + 1).padStart(2, '0'); +const year = date.getFullYear(); +return `${day}/${month}/${year}`; } function resetUI() { - if (recordedTestCasesDiv) { - recordedTestCasesDiv.innerHTML = ""; - } - if (recordStatus) { - recordStatus.style.display = "none"; - recordStatus.textContent = ""; - } - if (viewRecordLogsButton) { - viewRecordLogsButton.style.display = "none"; - } - if (viewTestLogsButton) { - viewTestLogsButton.style.display = "none"; - } +if (recordedTestCasesDiv) { + recordedTestCasesDiv.innerHTML = ""; +} +if (recordStatus) { + recordStatus.style.display = "none"; + recordStatus.textContent = ""; +} +if (viewRecordLogsButton) { + viewRecordLogsButton.style.display = "none"; +} +if (viewTestLogsButton) { + viewTestLogsButton.style.display = "none"; +} - if (testResultsDiv) { - testResultsDiv.innerHTML = ""; - } - if (testStatus) { - testStatus.textContent = ""; - testStatus.style.display = "none"; - } - if (testSuiteNameDiv) { - testSuiteNameDiv.innerHTML = ""; - } - if (totalTestCasesDiv) { - totalTestCasesDiv.innerHTML = ""; - } - if (testCasesPassedDiv) { - testCasesPassedDiv.innerHTML = ""; - } - if (testCasesFailedDiv) { - testCasesFailedDiv.innerHTML = ""; - } - if (lastTestResultsDiv) { - lastTestResultsDiv.innerHTML = ""; - } - if (viewCompleteSummaryButton) { - viewCompleteSummaryButton.style.display = "none"; - } - if (upperOutputDiv) { - upperOutputDiv.style.display = "none"; - } + +if (testResultsDiv) { + testResultsDiv.innerHTML = ""; +} +if (testStatus) { + testStatus.textContent = ""; + testStatus.style.display = "none"; +} +if (testSuiteNameDiv) { + testSuiteNameDiv.innerHTML = ""; +} +if (totalTestCasesDiv) { + totalTestCasesDiv.innerHTML = ""; +} +if (testCasesPassedDiv) { + testCasesPassedDiv.innerHTML = ""; +} +if (testCasesFailedDiv) { + testCasesFailedDiv.innerHTML = ""; +} +if (lastTestResultsDiv) { + lastTestResultsDiv.innerHTML = ""; +} +if (viewCompleteSummaryButton) { + viewCompleteSummaryButton.style.display = "none"; +} +if (upperOutputDiv) { + upperOutputDiv.style.display = "none"; +} } + if (openRecordPageButton) { - openRecordPageButton.addEventListener('click', async () => { - console.log("openRecordPageButton clicked"); - vscode.postMessage({ - type: "navigate", - value: "Keploy" - }); +openRecordPageButton.addEventListener('click', async () => { + console.log("openRecordPageButton clicked"); + vscode.postMessage({ + type: "navigate", + value: "Keploy", + eventName:"OpenRecordPageButtonClicked" }); +}); } + + if (openTestPageButton) { - openTestPageButton.addEventListener('click', async () => { - console.log("openTestPageButton clicked"); - vscode.postMessage({ - type: "navigate", - value: "Test" - }); +openTestPageButton.addEventListener('click', async () => { + console.log("openTestPageButton clicked"); + vscode.postMessage({ + type: "navigate", + value: "Test", + eventName:"OpenTestPageButtonClicked" }); +}); + } if (rerunTestSuiteButton) { - rerunTestSuiteButton.addEventListener('click', async () => { - console.log("rerunTestSuiteButton clicked"); - vscode.postMessage({ - type: "navigate", - value: "KeployHome" - }); +rerunTestSuiteButton.addEventListener('click', async () => { + console.log("rerunTestSuiteButton clicked"); + vscode.postMessage({ + type: "navigate", + value: "KeployHome", + eventName:"RerunTestSuiteButtonClicked" }); +}); } if(backConfigbutton){ - backConfigbutton.addEventListener('click',async () =>{ - console.log("back button clicked man." , selectedIconButton.textContent); - if(selectedIconButton.textContent == '1'){ - console.log("selectedIconButton: " , selectedIconButton.textContent ); - console.log("backconfig button clicked") - - if(actionStarted == true){ - vscode.postMessage({ - type: "stopRecordingCommand", - value: `Stop Recording` - }); - - vscode.postMessage({ - type: "stopTestingCommand", - value: `Stop Testing` - }); +backConfigbutton.addEventListener('click',async () =>{ + console.log("back button clicked man." , selectedIconButton.textContent); + if(selectedIconButton.textContent == '1'){ + console.log("selectedIconButton: " , selectedIconButton.textContent ); + console.log("backconfig button clicked") + + if (actionStarted == true) { vscode.postMessage({ - type:"navigate", - value:"IntegrationTest" - }) - - }else{ - vscode.postMessage({ - type:"navigate", - value:"Config" - }) - } - }else{ - + type: "stopRecordingCommand", + value: `Stop Recording`, + eventName: 'StopRecordingCommandSent', + }); + vscode.postMessage({ - type:"navigate", - value:"IntegrationTest" - }) - } - }) -}else{ - console.log("no back butoon"); -} + type: "stopTestingCommand", + value: `Stop Testing`, + eventName: 'StopTestingCommandSent', + }); -if (navigateToConfigButton) { - console.log("here is button") - navigateToConfigButton.addEventListener('click', async () => { + + vscode.postMessage({ + type: "navigate", + value: "IntegrationTest", + eventName: 'NavigateToIntegrationTest', + }); + + + } else { + vscode.postMessage({ + type: "navigate", + value: "Config", + eventName: 'NavigateToVsCodeHomeScreen', + }); + } + } else { vscode.postMessage({ type: "navigate", - value: "Config" + value: "IntegrationTest", + eventName: 'NavigateToIntegrationTest', }); } - ); +}); +} else { +console.log("no back button"); +} + + +if (navigateToConfigButton) { +console.log("here is button") +navigateToConfigButton.addEventListener('click', async () => { + vscode.postMessage({ + type: "navigate", + value: "Config", + eventName: 'NavigateToConfigButtonClicked', + }); +} +); } + if (backtoHome) { - backtoHome.addEventListener('click', async () => { - vscode.postMessage({ - type: "navigate", - value: "Config" - }); - } - ); +backtoHome.addEventListener('click', async () => { + vscode.postMessage({ + type: "navigate", + value: "Config", + eventName: 'BackToHomeButtonClicked', + }); +} +); } + // if (selectRecordFolderButton) { // selectRecordFolderButton.addEventListener('click', async () => { // console.log("selectRecordFolderButton clicked"); @@ -212,650 +232,755 @@ if (backtoHome) { // }); // } + if (viewTestLogsButton) { - viewTestLogsButton.addEventListener('click', async () => { - console.log("viewTestLogsButton clicked"); - vscode.postMessage({ - type: "viewLogs", - value: `logs/test_mode.log` - }); +viewTestLogsButton.addEventListener('click', async () => { + console.log("viewTestLogsButton clicked"); + vscode.postMessage({ + type: "viewLogs", + value: `logs/test_mode.log`, + eventName: 'ViewTestLogsButtonClicked', }); +}); } + if (viewRecordLogsButton) { - viewRecordLogsButton.addEventListener('click', async () => { - console.log("viewRecordLogsButton clicked"); - vscode.postMessage({ - type: "viewLogs", - value: `logs/record_mode.log` - }); +viewRecordLogsButton.addEventListener('click', async () => { + console.log("viewRecordLogsButton clicked"); + vscode.postMessage({ + type: "viewLogs", + value: `logs/record_mode.log`, + eventName: 'ViewRecordLogsButtonClicked', }); + +}); + + } + + if (startRecordingButton) { - startRecordingButton.addEventListener('click', async () => { - console.log("startRecordingButton clicked"); - actionStarted = true; - resetUI(); - // let commandValue = appCommand.value; - - // console.log('Command value:', commandValue); - - // FilePath = document.getElementById('projectFolder').value; - // if (FilePath === "") { - // FilePath = "./"; - // } - // const generatedRecordCommand = document.getElementById('generatedRecordCommand'); - vscode.postMessage({ - type: "startRecordingCommand", - value: `Recording Command...`, - // command: "./test-app-url-shortener", - // filePath: "./", - // generatedRecordCommand: "" - }); +startRecordingButton.addEventListener('click', async () => { + console.log("startRecordingButton clicked"); + actionStarted = true; + resetUI(); + // let commandValue = appCommand.value; + + + // console.log('Command value:', commandValue); + + + // FilePath = document.getElementById('projectFolder').value; + // if (FilePath === "") { + // FilePath = "./"; + // } + // const generatedRecordCommand = document.getElementById('generatedRecordCommand'); + vscode.postMessage({ + type: "startRecordingCommand", + value: `Recording Command...`, + eventName: 'StartRecordingButtonClicked', // Include eventName }); +}); } if (stopRecordingButton) { - stopRecordingButton.addEventListener('click', async () => { - console.log("stopRecordingButton clicked"); - actionStarted = false; - vscode.postMessage({ - type: "stopRecordingCommand", - value: `Stop Recording` - }); +stopRecordingButton.addEventListener('click', async () => { + console.log("stopRecordingButton clicked"); + actionStarted = false; + vscode.postMessage({ + type: "stopRecordingCommand", + value: `Stop Recording`, + eventName: 'StopRecordingButtonClicked', }); +}); } if (startTestButton) { - startTestButton.addEventListener('click', async () => { - console.log("startTestButton clicked"); - actionStarted = true; - resetUI(); - - // const commandValue = appCommand.value; - // console.log('Command value:', commandValue); - // FilePath = document.getElementById('projectFolder').value; - // if (FilePath === "") { - // FilePath = "./"; - // } - // const generatedTestCommand = document.getElementById('generatedTestCommand'); - vscode.postMessage({ - type: "startTestingCommand", - value: `Testing Command...`, - // command: "./test-app-url-shortener", - // filePath: "./", - // generatedTestCommand: "" - }); +startTestButton.addEventListener('click', async () => { + console.log("startTestButton clicked"); + actionStarted = true; + resetUI(); + + + // const commandValue = appCommand.value; + // console.log('Command value:', commandValue); + // FilePath = document.getElementById('projectFolder').value; + // if (FilePath === "") { + // FilePath = "./"; + // } + // const generatedTestCommand = document.getElementById('generatedTestCommand'); + vscode.postMessage({ + type: "startTestingCommand", + value: `Testing Command...`, + eventName: 'StartTestingButtonClicked', + // command: "./test-app-url-shortener", + // filePath: "./", + // generatedTestCommand: "" }); +}); } if (stopTestButton) { - stopTestButton.addEventListener('click', async () => { - console.log("stopTestButton clicked"); - actionStarted = false; - vscode.postMessage({ - type: "stopTestingCommand", - value: `Stop Testing` - }); +stopTestButton.addEventListener('click', async () => { + console.log("stopTestButton clicked"); + actionStarted = false; + vscode.postMessage({ + type: "stopTestingCommand", + value: `Stop Testing`, + eventName: 'StopTestingButtonClicked', }); +}); } + if (viewCompleteSummaryButton) { - viewCompleteSummaryButton.addEventListener('click', async () => { - console.log("viewCompleteSummaryButton clicked"); +viewCompleteSummaryButton.addEventListener('click', async () => { + console.log("viewCompleteSummaryButton clicked"); - vscode.postMessage({ - type: "navigate", - value: `Testresults` - }); - vscode.postMessage({ - type: "viewCompleteSummary", - value: `View Complete Summary` - }); + vscode.postMessage({ + type: "navigate", + value: `Testresults`, + }); + + + vscode.postMessage({ + type: "viewCompleteSummary", + value: `View Complete Summary`, + eventName: 'ViewCompleteSummaryButtonClicked', }); +}); + } + if (initialiseConfigButton) { - console.log("initialiseConfigButton inside if", initialiseConfigButton); - initialiseConfigButton.addEventListener('click', async () => { - console.log("initialiseConfigButton clicked"); - const path = document.getElementById('configPath').value; - const command = document.getElementById('configCommand').value; - vscode.postMessage({ - type: "initialiseConfig", - value: `Initialise Config`, - command: command, - path: path - }); +console.log("initialiseConfigButton inside if", initialiseConfigButton); +initialiseConfigButton.addEventListener('click', async () => { + console.log("initialiseConfigButton clicked"); + const path = document.getElementById('configPath').value; + const command = document.getElementById('configCommand').value; + vscode.postMessage({ + type: "initialiseConfig", + value: `Initialise Config`, + command: command, + path: path, + eventName: 'InitialiseConfigButtonClicked', }); +}); } + if (displayPreviousTestResults) { - displayPreviousTestResults.addEventListener('click', async () => { - console.log("displayPreviousTestResults clicked"); - console.log("stopping the recording and testing") - vscode.postMessage({ - type: "stopRecordingCommand", - value: `Stop Recording` - }); +displayPreviousTestResults.addEventListener('click', async () => { + console.log("displayPreviousTestResults clicked"); + console.log("stopping the recording and testing") + vscode.postMessage({ + type: "stopRecordingCommand", + value: `Stop Recording`, + eventName: 'DisplayPreviousTestResultsButtonClicked', + }); - vscode.postMessage({ - type: "stopTestingCommand", - value: `Stop Testing` - }); - vscode.postMessage({ - type: "viewPreviousTestResults", - value: `viewPreviousTestResults` - }); + + vscode.postMessage({ + type: "stopTestingCommand", + value: `Stop Testing` + }); + + + vscode.postMessage({ + type: "viewPreviousTestResults", + value: `viewPreviousTestResults` }); +}); + } + if (openConfigButton) { - openConfigButton.addEventListener('click', async () => { - console.log("openConfigButton clicked"); - console.log("stopping the recording and testing") - - vscode.postMessage({ - type: "stopRecordingCommand", - value: `Stop Recording` - }); +openConfigButton.addEventListener('click', async () => { + console.log("openConfigButton clicked"); + console.log("stopping the recording and testing") + vscode.postMessage({ + type: "stopRecordingCommand", + value: `Stop Recording`, + eventName: 'OpenConfigButtonClicked', + }); - vscode.postMessage({ - type: "stopTestingCommand", - value: `Stop Testing` - }); - vscode.postMessage({ - type: "openConfigFile", - value: `/keploy.yml` - }); + vscode.postMessage({ + type: "stopRecordingCommand", + value: `Stop Recording`, + eventName: 'OpenConfigButtonClicked', }); + + + + + vscode.postMessage({ + type: "stopTestingCommand", + value: `Stop Testing` + }); + vscode.postMessage({ + type: "openConfigFile", + value: `/keploy.yml`, + }); +}); } if (setupConfigButton) { - setupConfigButton.addEventListener('click', async => { - console.log("setupConfigButton clicked"); - vscode.postMessage({ - type: "openConfigFile", - value: `/keploy.yml` - }); +setupConfigButton.addEventListener('click', async => { + console.log("setupConfigButton clicked"); + vscode.postMessage({ + type: "openConfigFile", + value: `/keploy.yml`, + eventName: 'SetupConfigButtonClicked', }); +}); } + document.addEventListener('ciCdStepClick', function (e) { - // Logic to handle CI/CD setup click event - if (e.detail.step === 'ci-cd-setup') { - console.log('CI/CD setup step clicked'); - // Perform your action here, such as redirecting or opening something in the sidebar - // Example: Trigger navigation or link opening logic - vscode.postMessage({ - type: "openLink", - url: "https://keploy.io/docs", // Replace this with the URL you want to navigate to - });// Example of opening a link +// Logic to handle CI/CD setup click event +if (e.detail.step === 'ci-cd-setup') { + console.log('CI/CD setup step clicked'); + // Perform your action here, such as redirecting or opening something in the sidebar + // Example: Trigger navigation or link opening logic + vscode.postMessage({ + type: "openLink", + url: "https://keploy.io/docs", // Replace this with the URL you want to navigate to + eventName: 'CI/CDSetupStepClicked', + });// Example of opening a link } }); document.addEventListener('addUsersClick', function (e) { - // Logic to handle CI/CD setup click event - if (e.detail.step === 'add-users') { - console.log('add users step clicked'); - // Perform your action here, such as redirecting or opening something in the sidebar - // Example: Trigger navigation or link opening logic - vscode.postMessage({ - type: "openLink", - url: "https://app.keploy.io", // Replace this with the URL you want to navigate to - });// Example of opening a link +// Logic to handle CI/CD setup click event +if (e.detail.step === 'add-users') { + console.log('add users step clicked'); + // Perform your action here, such as redirecting or opening something in the sidebar + // Example: Trigger navigation or link opening logic + vscode.postMessage({ + type: "openLink", + url: "https://app.keploy.io", // Replace this with the URL you want to navigate to + eventName:"AddUsersStepClicked-OpenKeployLink" + });// Example of opening a link - vscode.postMessage({ - type:"progressStatus", - value:"false" - }) - } + + vscode.postMessage({ + type:"progressStatus", + value:"false", + }) +} }); + // Listen for custom events from the Svelte component document.addEventListener('getKeployConfigForSvelte', () => { - vscode.postMessage({ - type: 'getKeployConfig', - }); +vscode.postMessage({ + type: 'getKeployConfig', + eventName: 'getKeployConfigForSvelte', + +}); }); + + document.addEventListener('updateKeployConfig', (e) => { - const config = e.detail.config; - vscode.postMessage({ - type: 'updateKeployConfig', - config: config, - }); +const config = e.detail.config; +vscode.postMessage({ + type: 'updateKeployConfig', + config: config, + eventName: 'UpdatedKeployConfig', +}); }); + + // Handle messages sent from the extension window.addEventListener('message', event => { - const message = event.data; - console.log("message", message); +const message = event.data; +console.log("message", message); - if(message.type === "progressBarStatus"){ - if(message.value == false){ - ProgressStepperContainer.style.display = "none"; - } + +if(message.type === "progressBarStatus"){ + if(message.value == false){ + ProgressStepperContainer.style.display = "none"; } +} - if (message.type === 'navigateToHome') { - vscode.postMessage({ - type: "navigate", - value: "KeployHome" - }); - } - if (message.type === 'updateStatus') { - console.log("message.value", message.value); + +if (message.type === 'navigateToHome') { + vscode.postMessage({ + type: "navigate", + value: "KeployHome", + eventName: 'NavigateToHome', + }); +} +if (message.type === 'updateStatus') { + console.log("message.value", message.value); + + +} +else if (message.type === 'error') { + console.error(message.value); +} +else if (message.type === 'success') { + console.log(message.value); +} +else if (message.type === 'recordfile') { + console.log(message.value); + const projectFolder = document.getElementById('projectFolder'); + if (projectFolder) { + projectFolder.style.display = "block"; + projectFolder.value = message.value; + FilePath = message.value; } - else if (message.type === 'error') { - console.error(message.value); +} +else if (message.type === 'testcaserecorded') { + console.log("message.textContent", message.textContent); + if(stopRecordingButton){ + stopRecordingButton.click(); } - else if (message.type === 'success') { - console.log(message.value); + recordStatus.style.display = "block"; + recordedTestCasesDiv.style.display = "grid"; + + + if (message.error === true) { + recordStatus.textContent = `Failed To Record Test Cases`; + recordStatus.classList.add("error"); + const errorMessage = document.createElement('p'); + errorMessage.textContent = message.textContent; + errorMessage.classList.add("error"); + recordedTestCasesDiv.appendChild(errorMessage); + viewRecordLogsButton.style.display = "block"; + viewTestLogsButton.style.display = "block"; + viewTestLogsButton.disabled = true; + viewTestLogsButton.style.cursor = "not-allowed"; + return; } - else if (message.type === 'recordfile') { - console.log(message.value); - const projectFolder = document.getElementById('projectFolder'); - if (projectFolder) { - projectFolder.style.display = "block"; - projectFolder.value = message.value; - FilePath = message.value; - } + + + if (message.noTestCases === true) { + viewRecordLogsButton.style.display = "block"; + viewTestLogsButton.style.display = "block"; + viewTestLogsButton.disabled = true; + viewTestLogsButton.style.cursor = "not-allowed"; + recordStatus.textContent = `No Test Cases Recorded`; + recordedTestCasesDiv.style.display = "none"; + recordStatus.classList.add("info"); + return; } - else if (message.type === 'testcaserecorded') { - console.log("message.textContent", message.textContent); - if(stopRecordingButton){ - stopRecordingButton.click(); - } - recordStatus.style.display = "block"; - recordedTestCasesDiv.style.display = "grid"; - - if (message.error === true) { - recordStatus.textContent = `Failed To Record Test Cases`; - recordStatus.classList.add("error"); - const errorMessage = document.createElement('p'); - errorMessage.textContent = message.textContent; - errorMessage.classList.add("error"); - recordedTestCasesDiv.appendChild(errorMessage); - viewRecordLogsButton.style.display = "block"; - viewTestLogsButton.style.display = "block"; - viewTestLogsButton.disabled = true; - viewTestLogsButton.style.cursor = "not-allowed"; - return; - } - if (message.noTestCases === true) { - viewRecordLogsButton.style.display = "block"; - viewTestLogsButton.style.display = "block"; - viewTestLogsButton.disabled = true; - viewTestLogsButton.style.cursor = "not-allowed"; - recordStatus.textContent = `No Test Cases Recorded`; - recordedTestCasesDiv.style.display = "none"; - recordStatus.classList.add("info"); - return; - } - recordStatus.textContent = `Test Cases Recorded`; - recordStatus.classList.add("success"); - console.log(message.textContent); + recordStatus.textContent = `Test Cases Recorded`; + recordStatus.classList.add("success"); + console.log(message.textContent); - if (recordedTestCasesDiv) { - let testSetDropdown = document.getElementById(message.testSetName); - if (!testSetDropdown) { - // Create a dropdown for the new test set - testSetDropdown = document.createElement('div'); - testSetDropdown.id = message.testSetName; - testSetDropdown.classList.add("dropdown-container"); + if (recordedTestCasesDiv) { + let testSetDropdown = document.getElementById(message.testSetName); - // Create a button to act as the dropdown toggle - const dropdownToggle = document.createElement('div'); - dropdownToggle.classList.add("dropdown-header"); - // Create the toggle text - const toggleText = document.createElement('span'); - toggleText.textContent = message.testSetName; + if (!testSetDropdown) { + // Create a dropdown for the new test set + testSetDropdown = document.createElement('div'); + testSetDropdown.id = message.testSetName; + testSetDropdown.classList.add("dropdown-container"); - // Create the dropdown icon - const dropdownIcon = document.createElement('span'); - dropdownIcon.className = 'dropdown-icon'; - // Append text and icon to the toggle - dropdownToggle.appendChild(toggleText); - dropdownToggle.appendChild(dropdownIcon); + // Create a button to act as the dropdown toggle + const dropdownToggle = document.createElement('div'); + dropdownToggle.classList.add("dropdown-header"); - // Create a container for the test cases - const testCaseContainer = document.createElement('div'); - testCaseContainer.classList.add("dropdown-content"); - testCaseContainer.style.display = "none"; // Hide initially - // Add toggle functionality - dropdownToggle.addEventListener('click', () => { - testCaseContainer.style.display = testCaseContainer.style.display === "none" ? "block" : "none"; - dropdownIcon.classList.toggle('open'); // Update icon based on dropdown state - }); + // Create the toggle text + const toggleText = document.createElement('span'); + toggleText.textContent = message.testSetName; - // Append the toggle and container to the dropdown - testSetDropdown.appendChild(dropdownToggle); - testSetDropdown.appendChild(testCaseContainer); - recordedTestCasesDiv.appendChild(testSetDropdown); - } + // Create the dropdown icon + const dropdownIcon = document.createElement('span'); + dropdownIcon.className = 'dropdown-icon'; + + + // Append text and icon to the toggle + dropdownToggle.appendChild(toggleText); + dropdownToggle.appendChild(dropdownIcon); + + + // Create a container for the test cases + const testCaseContainer = document.createElement('div'); + testCaseContainer.classList.add("dropdown-content"); + testCaseContainer.style.display = "none"; // Hide initially - // Create the test case element - const testCaseElement = document.createElement('button'); - testCaseElement.classList.add("recordedTestCase"); - testCaseElement.addEventListener('click', async () => { - vscode.postMessage({ - type: "openRecordedTestFile", - value: message.path - }); + + // Add toggle functionality + dropdownToggle.addEventListener('click', () => { + testCaseContainer.style.display = testCaseContainer.style.display === "none" ? "block" : "none"; + dropdownIcon.classList.toggle('open'); // Update icon based on dropdown state }); - testCaseElement.textContent = message.textContent; - // Find the container and append the test case element - const testCaseContainer = testSetDropdown.querySelector('.dropdown-content'); - testCaseContainer.appendChild(testCaseElement); - } - } + // Append the toggle and container to the dropdown + testSetDropdown.appendChild(dropdownToggle); + testSetDropdown.appendChild(testCaseContainer); - else if (message.type === "testResults") { - console.log("message.value", message.value); - const testCaseElement = document.createElement('p'); - //click the stop testing button - if (stopTestButton) { - stopTestButton.click(); - } - testCaseElement.textContent = message.textSummary; - if (message.textSummary.includes("test passed")) { - testCaseElement.classList.add("success"); - } - else if (message.textSummary.includes("test failed")) { - //split the textSummary - const numErrors = message.textSummary.split(":")[1]; - if (numErrors !== " 0") { - viewTestLogsButton.style.display = "block"; - viewTestLogsButton.disabled = false; - viewTestLogsButton.style.cursor = "pointer"; - viewRecordLogsButton.style.display = "block"; - } - testCaseElement.classList.add("error"); - } - else { - testCaseElement.classList.add("info"); + recordedTestCasesDiv.appendChild(testSetDropdown); } - if (message.isCompleteSummary === true) { - console.log("message.isCompleteSummary", message.isCompleteSummary); - console.log("message.textSummary", message.textSummary); - let messageList = message.textSummary.split("\t"); - //remove all "" from the list - messageList = messageList.filter(function (el) { - return el !== ''; + + + // Create the test case element + const testCaseElement = document.createElement('button'); + testCaseElement.classList.add("recordedTestCase"); + testCaseElement.addEventListener('click', async () => { + vscode.postMessage({ + type: "openRecordedTestFile", + value: message.path, + eventName: 'OpenRecordedTestFileClicked', }); - console.log("messageList", messageList); - const testSuiteNameElement = document.createElement('p'); - testSuiteNameElement.textContent = messageList[0]; - testSuiteNameDiv.appendChild(testSuiteNameElement); - const testCasesTotalElement = document.createElement('p'); - testCasesTotalElement.textContent = messageList[1]; - totalTestCasesDiv.appendChild(testCasesTotalElement); - const testCasesPassedElement = document.createElement('p'); - testCasesPassedElement.textContent = messageList[2]; - testCasesPassedDiv.appendChild(testCasesPassedElement); - const testCasesFailedElement = document.createElement('p'); - testCasesFailedElement.textContent = messageList[3]; - testCasesFailedDiv.appendChild(testCasesFailedElement); - return; + }); - } - if (message.error === true) { - viewCompleteSummaryButton.style.display = "none"; - viewTestLogsButton.style.display = "block"; - viewTestLogsButton.disabled = false; - viewTestLogsButton.style.cursor = "pointer"; - viewRecordLogsButton.style.display = "block"; - } - else { - viewCompleteSummaryButton.style.display = "block"; - completeSummaryHr.style.display = "block"; - } - if (message.error === true) { + + testCaseElement.textContent = message.textContent; + + + // Find the container and append the test case element + const testCaseContainer = testSetDropdown.querySelector('.dropdown-content'); + testCaseContainer.appendChild(testCaseElement); + } +} + + +else if (message.type === "testResults") { + console.log("message.value", message.value); + const testCaseElement = document.createElement('p'); + //click the stop testing button + if (stopTestButton) { + stopTestButton.click(); + } + testCaseElement.textContent = message.textSummary; + if (message.textSummary.includes("test passed")) { + testCaseElement.classList.add("success"); + } + else if (message.textSummary.includes("test failed")) { + //split the textSummary + const numErrors = message.textSummary.split(":")[1]; + if (numErrors !== " 0") { viewTestLogsButton.style.display = "block"; viewTestLogsButton.disabled = false; viewTestLogsButton.style.cursor = "pointer"; viewRecordLogsButton.style.display = "block"; - if (testStatus) { - testStatus.textContent = message.value; - testStatus.classList.add("error"); - } - else { - testResultsDiv.innerHTML = `

${message.value}

`; - } + + } - testResultsDiv.appendChild(testCaseElement); + testCaseElement.classList.add("error"); + } + else { + testCaseElement.classList.add("info"); + } + if (message.isCompleteSummary === true) { + console.log("message.isCompleteSummary", message.isCompleteSummary); + console.log("message.textSummary", message.textSummary); + let messageList = message.textSummary.split("\t"); + //remove all "" from the list + messageList = messageList.filter(function (el) { + return el !== ''; + }); + console.log("messageList", messageList); + const testSuiteNameElement = document.createElement('p'); + testSuiteNameElement.textContent = messageList[0]; + testSuiteNameDiv.appendChild(testSuiteNameElement); + const testCasesTotalElement = document.createElement('p'); + testCasesTotalElement.textContent = messageList[1]; + totalTestCasesDiv.appendChild(testCasesTotalElement); + const testCasesPassedElement = document.createElement('p'); + testCasesPassedElement.textContent = messageList[2]; + testCasesPassedDiv.appendChild(testCasesPassedElement); + const testCasesFailedElement = document.createElement('p'); + testCasesFailedElement.textContent = messageList[3]; + testCasesFailedDiv.appendChild(testCasesFailedElement); + return; + + } - else if (message.type === "testfile") { - const projectFolder = document.getElementById('projectFolder'); - if (projectFolder) { - projectFolder.value = message.value; - FilePath = message.value; + if (message.error === true) { + viewCompleteSummaryButton.style.display = "none"; + viewTestLogsButton.style.display = "block"; + viewTestLogsButton.disabled = false; + viewTestLogsButton.style.cursor = "pointer"; + viewRecordLogsButton.style.display = "block"; + } + else { + viewCompleteSummaryButton.style.display = "block"; + completeSummaryHr.style.display = "block"; + } + if (message.error === true) { + viewTestLogsButton.style.display = "block"; + viewTestLogsButton.disabled = false; + viewTestLogsButton.style.cursor = "pointer"; + viewRecordLogsButton.style.display = "block"; + if (testStatus) { + testStatus.textContent = message.value; + testStatus.classList.add("error"); } - const testCommandDiv = document.getElementById('testCommandInput'); - if (testCommandDiv) { - testCommandDiv.style.display = "block"; + else { + testResultsDiv.innerHTML = `

${message.value}

`; } - + } + testResultsDiv.appendChild(testCaseElement); +} +else if (message.type === "testfile") { + const projectFolder = document.getElementById('projectFolder'); + if (projectFolder) { + projectFolder.value = message.value; + FilePath = message.value; + } + const testCommandDiv = document.getElementById('testCommandInput'); + if (testCommandDiv) { + testCommandDiv.style.display = "block"; } - else if (message.type === "configNotFound") { - if (configNotFound) { - configNotFound.classList.add("error"); - configNotFound.textContent = message.value; - } - const configInstruction = document.createElement('pre'); - configInstruction.classList.add("info"); - configInstruction.textContent = `Run the below command to generate the config file`; - configNotFound.appendChild(configInstruction); - const configCommand = document.createElement('pre'); - configCommand.classList.add("terminal"); - configCommand.textContent = `keploy config --generate`; - configCommand.addEventListener('click', async () => { - navigator.clipboard.writeText('keploy config --generate'); - }); - configNotFound.appendChild(configCommand); + +} + + +else if (message.type === "configNotFound") { + if (configNotFound) { + configNotFound.classList.add("error"); + configNotFound.textContent = message.value; } + const configInstruction = document.createElement('pre'); + configInstruction.classList.add("info"); + configInstruction.textContent = `Run the below command to generate the config file`; + configNotFound.appendChild(configInstruction); + const configCommand = document.createElement('pre'); + configCommand.classList.add("terminal"); + configCommand.textContent = `keploy config --generate`; + configCommand.addEventListener('click', async () => { + navigator.clipboard.writeText('keploy config --generate'); + }); + configNotFound.appendChild(configCommand); +} + + +else if (message.type === "configUninitialized") { + try { + const initialiseConfigDiv = document.getElementById('initialiseConfig'); + const keployConfigInfo = document.getElementById('keployConfigInfo'); + keployConfigInfo.style.display = "none"; + initialiseConfigDiv.style.display = "grid"; + initialiseConfigButton.style.display = "block"; - else if (message.type === "configUninitialized") { - try { - const initialiseConfigDiv = document.getElementById('initialiseConfig'); - const keployConfigInfo = document.getElementById('keployConfigInfo'); - keployConfigInfo.style.display = "none"; - initialiseConfigDiv.style.display = "grid"; - initialiseConfigButton.style.display = "block"; - } - catch (error) { - console.log("error", error); - } } + catch (error) { + console.log("error", error); + } +} - if (message.type === 'aggregatedTestResults') { - console.log("message.value", message.value); - const lastTestResultsDiv = document.getElementById('lastTestResults'); - const totalTestCasesDiv = document.getElementById('totalTestCases'); - const testSuiteNameDiv = document.getElementById('testSuiteName'); - const testCasesPassedDiv = document.getElementById('testCasesPassed'); - const testCasesFailedDiv = document.getElementById('testCasesFailed'); - - // Clear previous content - if (totalTestCasesDiv) { totalTestCasesDiv.innerHTML = ''; } - if (testSuiteNameDiv) { testSuiteNameDiv.innerHTML = ''; } - if (testCasesPassedDiv) { testCasesPassedDiv.innerHTML = ''; } - if (testCasesFailedDiv) { testCasesFailedDiv.innerHTML = ''; } - - if (message.error === true) { - - if (lastTestResultsDiv) { - const errorElement = document.createElement('p'); - errorElement.textContent = "No Test Runs Found"; - errorElement.classList.add("error"); - errorElement.id = "errorElement"; - lastTestResultsDiv.appendChild(errorElement); +if (message.type === 'aggregatedTestResults') { + console.log("message.value", message.value); + const lastTestResultsDiv = document.getElementById('lastTestResults'); + const totalTestCasesDiv = document.getElementById('totalTestCases'); + const testSuiteNameDiv = document.getElementById('testSuiteName'); + const testCasesPassedDiv = document.getElementById('testCasesPassed'); + const testCasesFailedDiv = document.getElementById('testCasesFailed'); + + + // Clear previous content + if (totalTestCasesDiv) { totalTestCasesDiv.innerHTML = ''; } + if (testSuiteNameDiv) { testSuiteNameDiv.innerHTML = ''; } + if (testCasesPassedDiv) { testCasesPassedDiv.innerHTML = ''; } + if (testCasesFailedDiv) { testCasesFailedDiv.innerHTML = ''; } + + + if (message.error === true) { + + + if (lastTestResultsDiv) { + const errorElement = document.createElement('p'); + errorElement.textContent = "No Test Runs Found"; + errorElement.classList.add("error"); + errorElement.id = "errorElement"; + lastTestResultsDiv.appendChild(errorElement); + } + } else { + // Group tests by date and then by report + const testsByDateAndReport = {}; + message.data.testResults.forEach(test => { + const date = test.date; + const report = test.report; + if (!testsByDateAndReport[date]) { + testsByDateAndReport[date] = {}; } - } else { - // Group tests by date and then by report - const testsByDateAndReport = {}; - message.data.testResults.forEach(test => { - const date = test.date; - const report = test.report; - if (!testsByDateAndReport[date]) { - testsByDateAndReport[date] = {}; - } - if (!testsByDateAndReport[date][report]) { - testsByDateAndReport[date][report] = []; - } - testsByDateAndReport[date][report].push(test); - }); + if (!testsByDateAndReport[date][report]) { + testsByDateAndReport[date][report] = []; + } + testsByDateAndReport[date][report].push(test); + }); + + + const testCasesTotalElement = document.createElement('p'); + testCasesTotalElement.textContent = `Total Test Cases : ${message.data.total}`; + if (totalTestCasesDiv) { totalTestCasesDiv.appendChild(testCasesTotalElement); } + + + const testCasesPassedElement = document.createElement('p'); + testCasesPassedElement.textContent = `Test Cases Passed : ${message.data.success}`; + if (testCasesPassedDiv) { testCasesPassedDiv.appendChild(testCasesPassedElement); } + + + const testCasesFailedElement = document.createElement('p'); + testCasesFailedElement.textContent = `Test Cases Failed : ${message.data.failure}`; + if (testCasesFailedDiv) { testCasesFailedDiv.appendChild(testCasesFailedElement); } + + + // Create and append dropdown structure based on testsByDateAndReport + const dropdownContainer = document.createElement('div'); + dropdownContainer.className = 'dropdown-container'; + - const testCasesTotalElement = document.createElement('p'); - testCasesTotalElement.textContent = `Total Test Cases : ${message.data.total}`; - if (totalTestCasesDiv) { totalTestCasesDiv.appendChild(testCasesTotalElement); } + for (const date in testsByDateAndReport) { + if (testsByDateAndReport.hasOwnProperty(date)) { + const reports = testsByDateAndReport[date]; - const testCasesPassedElement = document.createElement('p'); - testCasesPassedElement.textContent = `Test Cases Passed : ${message.data.success}`; - if (testCasesPassedDiv) { testCasesPassedDiv.appendChild(testCasesPassedElement); } - const testCasesFailedElement = document.createElement('p'); - testCasesFailedElement.textContent = `Test Cases Failed : ${message.data.failure}`; - if (testCasesFailedDiv) { testCasesFailedDiv.appendChild(testCasesFailedElement); } + const dropdownHeader = document.createElement('div'); + dropdownHeader.className = 'dropdown-header'; - // Create and append dropdown structure based on testsByDateAndReport - const dropdownContainer = document.createElement('div'); - dropdownContainer.className = 'dropdown-container'; - for (const date in testsByDateAndReport) { - if (testsByDateAndReport.hasOwnProperty(date)) { - const reports = testsByDateAndReport[date]; + // Get current date + const currentDate = new Date(); + const currentDateString = formatDate(currentDate); - const dropdownHeader = document.createElement('div'); - dropdownHeader.className = 'dropdown-header'; - // Get current date - const currentDate = new Date(); - const currentDateString = formatDate(currentDate); + // Get yesterday's date + const yesterday = new Date(currentDate); + yesterday.setDate(currentDate.getDate() - 1); + const yesterdayDateString = formatDate(yesterday); - // Get yesterday's date - const yesterday = new Date(currentDate); - yesterday.setDate(currentDate.getDate() - 1); - const yesterdayDateString = formatDate(yesterday); - if (currentDateString === date) { - dropdownHeader.textContent = `Today`; - } else if (yesterdayDateString === date) { - dropdownHeader.textContent = `Yesterday`; - } else { - dropdownHeader.textContent = `${date}`; + if (currentDateString === date) { + dropdownHeader.textContent = `Today`; + } else if (yesterdayDateString === date) { + dropdownHeader.textContent = `Yesterday`; + } else { + dropdownHeader.textContent = `${date}`; + } + + + // Add dropdown icon + const dropdownIcon = document.createElement('span'); + dropdownIcon.className = 'dropdown-icon'; + + + dropdownHeader.appendChild(dropdownIcon); + dropdownHeader.onclick = () => { + const content = document.getElementById(`dropdown${date}`); + if (content) { + content.classList.toggle('show'); + dropdownIcon.classList.toggle('open'); // Update icon based on dropdown state } + }; + + + const dropdownContent = document.createElement('div'); + dropdownContent.id = `dropdown${date}`; + dropdownContent.className = 'dropdown-content'; + + + for (const report in reports) { + if (reports.hasOwnProperty(report)) { + const reportDropdownHeader = document.createElement('div'); + reportDropdownHeader.className = 'dropdown-header'; + reportDropdownHeader.textContent = report; - // Add dropdown icon - const dropdownIcon = document.createElement('span'); - dropdownIcon.className = 'dropdown-icon'; - - dropdownHeader.appendChild(dropdownIcon); - dropdownHeader.onclick = () => { - const content = document.getElementById(`dropdown${date}`); - if (content) { - content.classList.toggle('show'); - dropdownIcon.classList.toggle('open'); // Update icon based on dropdown state - } - }; - - const dropdownContent = document.createElement('div'); - dropdownContent.id = `dropdown${date}`; - dropdownContent.className = 'dropdown-content'; - - for (const report in reports) { - if (reports.hasOwnProperty(report)) { - const reportDropdownHeader = document.createElement('div'); - reportDropdownHeader.className = 'dropdown-header'; - reportDropdownHeader.textContent = report; - - // Add dropdown icon for report - const reportDropdownIcon = document.createElement('span'); - reportDropdownIcon.className = 'dropdown-icon'; - - reportDropdownHeader.appendChild(reportDropdownIcon); - reportDropdownHeader.onclick = () => { - const content = document.getElementById(`dropdown${date}${report}`); - if (content) { - content.classList.toggle('show'); - reportDropdownIcon.classList.toggle('open'); // Update icon based on dropdown state - } - }; - - const reportDropdownContent = document.createElement('div'); - reportDropdownContent.id = `dropdown${date}${report}`; - reportDropdownContent.className = 'report-dropdown-content'; - - reports[report].forEach((test, index) => { - // Append individual test details - const testMethod = document.createElement('div'); - testMethod.textContent = `${test.method}`; - if (test.status === 'PASSED') { - testMethod.classList.add("testSuccess"); - } else { - testMethod.classList.add("testError"); - } - reportDropdownContent.appendChild(testMethod); - - const testName = document.createElement('div'); - testName.textContent = `${test.name}`; - testName.classList.add("testName"); - reportDropdownContent.appendChild(testName); - - testName.addEventListener('click', async () => { - vscode.postMessage({ - type: "openTestFile", - value: test.testCasePath - }); + + // Add dropdown icon for report + const reportDropdownIcon = document.createElement('span'); + reportDropdownIcon.className = 'dropdown-icon'; + + + reportDropdownHeader.appendChild(reportDropdownIcon); + reportDropdownHeader.onclick = () => { + const content = document.getElementById(`dropdown${date}${report}`); + if (content) { + content.classList.toggle('show'); + reportDropdownIcon.classList.toggle('open'); // Update icon based on dropdown state + } + }; + + + const reportDropdownContent = document.createElement('div'); + reportDropdownContent.id = `dropdown${date}${report}`; + reportDropdownContent.className = 'report-dropdown-content'; + + + reports[report].forEach((test, index) => { + // Append individual test details + const testMethod = document.createElement('div'); + testMethod.textContent = `${test.method}`; + if (test.status === 'PASSED') { + testMethod.classList.add("testSuccess"); + } else { + testMethod.classList.add("testError"); + } + reportDropdownContent.appendChild(testMethod); + + + const testName = document.createElement('div'); + testName.textContent = `${test.name}`; + testName.classList.add("testName"); + reportDropdownContent.appendChild(testName); + + + testName.addEventListener('click', async () => { + vscode.postMessage({ + type: "openTestFile", + value: test.testCasePath }); - testMethod.addEventListener('click', async () => { - vscode.postMessage({ - type: "openTestFile", - value: test.testCasePath - }); + }); + testMethod.addEventListener('click', async () => { + vscode.postMessage({ + type: "openTestFile", + value: test.testCasePath }); }); + }); - dropdownContent.appendChild(reportDropdownHeader); - dropdownContent.appendChild(reportDropdownContent); - } - } - dropdownContainer.appendChild(dropdownHeader); - dropdownContainer.appendChild(dropdownContent); + dropdownContent.appendChild(reportDropdownHeader); + dropdownContent.appendChild(reportDropdownContent); + } } - } - if (lastTestResultsDiv) { lastTestResultsDiv.appendChild(dropdownContainer); } + + dropdownContainer.appendChild(dropdownHeader); + dropdownContainer.appendChild(dropdownContent); + } } + + if (lastTestResultsDiv) { lastTestResultsDiv.appendChild(dropdownContainer); } } + +} + + }); diff --git a/src/extension.ts b/src/extension.ts index 3eef1ce..e8e6c0f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -521,13 +521,15 @@ export function activate(context: vscode.ExtensionContext) { const installationId = context.globalState.get('installationId') || generateInstallationId(); const extensionVersion = '1.0.0'; // Replace with your extension's version - // Create a Telemetry instance - const telemetry = new Telemetry({ - enabled: telemetryEnabled, - installationId: installationId as string, - extensionVersion: extensionVersion, - }); + // Initialize the singleton Telemetry instance + Telemetry.initialize({ + enabled: telemetryEnabled, + installationId: installationId as string, + extensionVersion: extensionVersion, + }); + // Example: Track an event when the extension is activated + const telemetry = Telemetry.getInstance(); // Example: Track an event when the extension is activated telemetry.trackEvent('ExtensionActivated'); @@ -536,8 +538,8 @@ export function activate(context: vscode.ExtensionContext) { context.globalState.update('installationId', installationId); } - const sidebarProvider = new SidebarProvider(context.extensionUri, context); - context.subscriptions.push( + const sidebarProvider = new SidebarProvider(context.extensionUri, context); + context.subscriptions.push( vscode.window.registerUriHandler({ async handleUri(uri) { // Extract the token and state from the URI query parameters @@ -626,10 +628,12 @@ export function activate(context: vscode.ExtensionContext) { // Register the sign-in command if not signed in } let signInCommand = vscode.commands.registerCommand('keploy.SignInWithGithub', async () => { + telemetry.trackEvent('SignInWithGithubClicked'); try { const result = await getGitHubAccessToken(); if (result) { + telemetry.trackEvent('GitHubAccessTokenRetrieved'); const { accessToken, email } = result; getInstallationID(); @@ -645,6 +649,7 @@ export function activate(context: vscode.ExtensionContext) { await context.globalState.update('SignedOthers', true); // if (isValid) { + telemetry.trackEvent('SignInWithGithubSuccess', { emailID }); vscode.window.showInformationMessage('You are now signed in!'); vscode.commands.executeCommand('setContext', 'keploy.signedIn', true); vscode.commands.executeCommand('setContext', 'keploy.signedOut', false); @@ -653,11 +658,13 @@ export function activate(context: vscode.ExtensionContext) { // } } else { + telemetry.trackEvent('SignInWithGithubValidationFailed'); console.log('Failed to get the session or email.'); vscode.window.showInformationMessage('Failed to sign in Keploy!'); } } catch (error) { // console.error('Error during sign-in:', error); + telemetry.trackEvent('SignInWithGithubError', { error: error }); vscode.window.showInformationMessage('Failed to sign in Keploy!'); } }); @@ -665,9 +672,12 @@ export function activate(context: vscode.ExtensionContext) { let signInWithOthersCommand = vscode.commands.registerCommand('keploy.SignInWithOthers', async () => { + telemetry.trackEvent('SignInWithOthersClicked'); try { await SignInWithOthers(); // The result will now be handled in the URI handler + telemetry.trackEvent('SignInWithOthersSuccess'); } catch (error) { + telemetry.trackEvent('SignInWithOthersError', { error }); // console.error('Error during sign-in:', error); vscode.window.showInformationMessage('Failed to sign in Keploy!'); } @@ -680,9 +690,12 @@ export function activate(context: vscode.ExtensionContext) { //defining another function for microsoft to redirect because functions with same command name cannot be added in package.json let signInWithMicrosoft = vscode.commands.registerCommand('keploy.SignInWithMicrosoft', async () => { + telemetry.trackEvent('SignInWithMicrosoftClicked'); try { await SignInWithOthers(); // The result will now be handled in the URI handler + telemetry.trackEvent('SignInWithMicrosoftSuccess'); } catch (error) { + telemetry.trackEvent('SignInWithMicrosoftError', { error }); // console.error('Error during sign-in:', error); vscode.window.showInformationMessage('Failed to sign in Keploy!'); } @@ -715,6 +728,7 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(viewKeployVersionDisposable); let viewChangeLogDisposable = vscode.commands.registerCommand('keploy.viewChangeLog', () => { + telemetry.trackEvent('ViewChangeLogClicked'); const changeLogUrl = 'https://marketplace.visualstudio.com/items?itemName=Keploy.keployio'; vscode.env.openExternal(vscode.Uri.parse(changeLogUrl)); } @@ -724,6 +738,7 @@ export function activate(context: vscode.ExtensionContext) { let viewDocumentationDisposable = vscode.commands.registerCommand('keploy.viewDocumentation', () => { const docsUrl = 'https://keploy.io/docs/'; vscode.env.openExternal(vscode.Uri.parse(docsUrl)); + } ); context.subscriptions.push(viewDocumentationDisposable); @@ -773,6 +788,10 @@ export function activate(context: vscode.ExtensionContext) { let showSidebarDisposable = vscode.commands.registerCommand('keploy.showSidebar', async (filePath: string, FunctionName: string, FileExtentionName: string) => { // Show the sidebar when this command is executed + telemetry.trackEvent('ShowSidebarCommandInvoked', { + functionName: FunctionName, + fileExtension: FileExtentionName + }); functionName = FunctionName; ExtentionName = FileExtentionName; FunctionFilePath = filePath; diff --git a/src/telemetry.ts b/src/telemetry.ts new file mode 100644 index 0000000..52ec719 --- /dev/null +++ b/src/telemetry.ts @@ -0,0 +1,88 @@ +// telemetry.ts +import * as https from 'https'; +import * as os from 'os'; + +class Telemetry { + private static instance: Telemetry; + + private enabled: boolean; + private installationId: string; + private extensionVersion: string; + private telemetryUrl: string = 'https://telemetry.keploy.io/analytics'; + + private constructor(options: { + enabled: boolean; + installationId: string; + extensionVersion: string; + }) { + this.enabled = options.enabled; + this.installationId = options.installationId; + this.extensionVersion = options.extensionVersion; + } + + public static initialize(options: { + enabled: boolean; + installationId: string; + extensionVersion: string; + }): void { + if (!Telemetry.instance) { + Telemetry.instance = new Telemetry(options); + console.log('Telemetry initialized with options:', options); + } + } + + public static getInstance(): Telemetry { + if (!Telemetry.instance) { + throw new Error("Telemetry not initialized. Call Telemetry.initialize() first."); + } + return Telemetry.instance; + } + + private sendTelemetry(eventType: string, data: Record = {}) { + if (!this.enabled) return; + console.log(`Telemetry: Sending event '${eventType}' with data:`, data); + + const event = { + EventType: eventType, + CreatedAt: Date.now(), + InstallationID: this.installationId, + OS: os.platform(), + KeployVersion: this.extensionVersion, + Arch: os.arch(), + Meta: data, + }; + + const postData = JSON.stringify(event); + + const options = { + hostname: 'telemetry.keploy.io', + port: 443, + path: '/analytics', + method: 'POST', + headers: { + 'Content-Type': 'application/json; charset=utf-8', + 'Content-Length': Buffer.byteLength(postData), + }, + }; + + const req = https.request(options, (res) => { + res.on('data', (d) => { + // Handle response if necessary + }); + }); + + req.on('error', (error) => { + console.error(`Telemetry error: ${error.message}`); + }); + + req.write(postData); + req.end(); + } + + public trackEvent(eventName: string, properties?: Record) { + console.log(`Telemetry: Tracking event '${eventName}' with properties:`, properties); + this.sendTelemetry(eventName, properties); + } +} + +export { Telemetry }; diff --git a/webviews/components/Config.svelte b/webviews/components/Config.svelte index 6c36f5c..828fd30 100644 --- a/webviews/components/Config.svelte +++ b/webviews/components/Config.svelte @@ -47,6 +47,7 @@ vscode.postMessage({ type: "navigate", value: "IntegrationTest", + eventName: "GenerateIntegrationTestButtonClicked" }); }else{ navigateToKeploy(); @@ -54,7 +55,9 @@ }else{ vscode.postMessage({ type: "navigate", - value: "UtgDocs" + value: "UtgDocs", + eventName: "GenerateUnitTestButtonClicked" + }); } diff --git a/webviews/components/IntegrationTest.svelte b/webviews/components/IntegrationTest.svelte index 4e38cd1..ea05a21 100644 --- a/webviews/components/IntegrationTest.svelte +++ b/webviews/components/IntegrationTest.svelte @@ -11,6 +11,14 @@ let isPrecheckDone = false; let projectType = ""; + + function trackEvent(value) { + vscode.postMessage({ + type: 'trackEvent', + value, + }); + } + function handleProjectTypeDetection(event) { if (event.data && event.data.type === 'projectDetected') { projectType = event.data.projectType; @@ -57,6 +65,7 @@ command: command, path: path }); + trackEvent("initializeConfig"); handleTestSelection("KeployHome"); } else { console.error("Command is required to initialize the config.");