Skip to content

Add real-time scanning tests (AST-99452) #1197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
75a6843
add real-time scanning tests
cx-sarah-chen Jun 30, 2025
64be9a7
Merge branch 'main' into feature/saraChen/addRealtimeTests
cx-sarah-chen Jun 30, 2025
4bf1fe4
add check for SCA vulnerability markers in OSS Scanner tests
cx-sarah-chen Jun 30, 2025
846c4df
refactor: comment out malicious markers expectation in OSS Scanner tests
cx-sarah-chen Jun 30, 2025
3447156
fix: enable OSS realtime scanner in tests and assert malicious markers
cx-sarah-chen Jun 30, 2025
92b5746
Update ci-linux.yml
cx-sarah-chen Jun 30, 2025
17658ae
fix: add console log for OSS realtime scanner checkbox state
cx-sarah-chen Jun 30, 2025
223284d
feat: implement OSS Scanner E2E tests for security issue detection an…
cx-sarah-chen Jun 30, 2025
76ef4b6
commit
cx-sarah-chen Jun 30, 2025
30a810e
fix: update build scripts to include E2E test project and improve OSS…
cx-sarah-chen Jun 30, 2025
7cad403
Update ci-linux.yml
cx-sarah-chen Jun 30, 2025
ebe84c0
fix: increase timeout for OSS scanner E2E test and sleep duration for…
cx-sarah-chen Jun 30, 2025
2951f0e
fix: add debugging output section for OSS Scanner E2E test
cx-sarah-chen Jul 1, 2025
fa0c56b
fix: add debugging output section and force test failure for OSS Scan…
cx-sarah-chen Jul 1, 2025
ea0c29b
fix: enhance OSS Scanner E2E test with detailed output logging and fo…
cx-sarah-chen Jul 1, 2025
eafbec5
fix: increase sleep duration for OSS Scanner E2E test and remove redu…
cx-sarah-chen Jul 1, 2025
5995eee
open folder
cx-sarah-chen Jul 1, 2025
d0e3918
fix: update OSS Scanner E2E test to improve folder navigation and red…
cx-sarah-chen Jul 1, 2025
5a202b6
fix: update OSS Scanner E2E tests to use wildcard for test files and …
cx-sarah-chen Jul 1, 2025
c177666
fix: update OSS Scanner E2E tests to open the correct folder path and…
cx-sarah-chen Jul 1, 2025
d4667d6
fix: improve OSS Scanner E2E test setup and folder navigation
cx-sarah-chen Jul 1, 2025
817e9b5
fix: refactor cleanup process in OSS Scanner E2E tests for reliability
cx-sarah-chen Jul 1, 2025
590386a
fix: replace editorView.closeAllEditors with bench.executeCommand for…
cx-sarah-chen Jul 2, 2025
a3c9bc8
fix: streamline OSS Scanner E2E tests setup and cleanup process for r…
cx-sarah-chen Jul 2, 2025
01d8519
fix: enhance OSS Scanner E2E tests setup and cleanup for improved rel…
cx-sarah-chen Jul 2, 2025
0af90ce
fix: improve OSS Scanner E2E tests setup for enhanced reliability
cx-sarah-chen Jul 2, 2025
e3a90b6
fix: streamline OSS Scanner E2E tests setup by consolidating folder o…
cx-sarah-chen Jul 2, 2025
8bb0d02
fix: enhance OSS Scanner E2E tests to validate detection of various s…
cx-sarah-chen Jul 2, 2025
dbb23c4
fix: update OSS Scanner E2E tests for improved clarity and functionality
cx-sarah-chen Jul 2, 2025
4e4117d
fix: comment out dynamic content change scan test for future reference
cx-sarah-chen Jul 2, 2025
1fb400d
fix: restore dynamic content change scan test functionality
cx-sarah-chen Jul 2, 2025
5dd6a57
fix: restore functionality for dynamic content change scan test
cx-sarah-chen Jul 2, 2025
240245f
fix: comment out restoration of original content in OSS Scanner E2E t…
cx-sarah-chen Jul 2, 2025
c24c7a2
fix: improve handling of editor reference and restore original conten…
cx-sarah-chen Jul 2, 2025
7e180b9
fix: comment out restoration of original content in OSS Scanner E2E t…
cx-sarah-chen Jul 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
with:
name: artifacts-${{ matrix.os }}
path: |
test-resources/screenshots/*.png
/tmp/test-resources/screenshots/
retention-days: 2
- name: Upload screenshots
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 #v4
Expand Down Expand Up @@ -103,7 +103,7 @@ jobs:
with:
name: artifacts-${{ matrix.os }}
path: |
test-resources/screenshots/*.png
/tmp/test-resources/screenshots/*.png
retention-days: 2
- name: Upload screenshots
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 #v4
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -934,19 +934,20 @@
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./ && npm run copytestproject && npm run copymedia",
"compile": "tsc -p ./ && npm run copytestproject && npm run copye2etestproject && npm run copymedia",
"lint": "eslint . --ext .ts --no-fix --max-warnings 0",
"lint:fix": "npm run lint -- --fix",
"watch": "tsc -w -p ./ && npm run copytestproject",
"watch": "tsc -w -p ./ && npm run copytestproject && npm run copye2etestproject",
"copytestproject": "copyfiles -u 2 \"src/resources/**/*\" out/test/ -E",
"copye2etestproject": "copyfiles -u 2 \"src/resources/**/*\" out/e2e/ -E",
"copymedia": "copyfiles \"media/icons/*\" out/ -E",
"configure-husky": "npx husky install && npx husky add .husky/pre-commit \"npx --no-install lint-staged\"",
"test": "export TEST=true && npm run compile && extest setup-and-run './out/test/**/*test.js' -c 1.87.2 -i -r .",
"win-test": "set TEST=true&& npm run compile && extest setup-and-run './out/test/**/*test.js' -c 1.87.2 -i -r .",
"unit-test": "mocha --require ts-node/register './src/unit/**/*.test.ts'",
"unit-coverage": "npx nyc npm run unit-test",
"test:ui-end-to-end": "export TEST=uiEndToEnd && npm run compile && extest setup-and-run './out/e2e/getScan.test.js' -c 1.87.2 -i -r .",
"win-test:ui-end-to-end": "set TEST=uiEndToEnd&& npm run compile && extest setup-and-run './out/e2e/getScan.test.js' -c 1.87.2 -i -r ."
"test:ui-end-to-end": "export TEST=uiEndToEnd && npm run compile && extest setup-and-run './out/e2e/*.test.js' -c 1.87.2 -i -r .",
"win-test:ui-end-to-end": "set TEST=uiEndToEnd&& npm run compile && extest setup-and-run './out/e2e/*.test.js' -c 1.87.2 -i -r ."
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.2",
Expand Down
79 changes: 73 additions & 6 deletions src/e2e/getScan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import {
VSBrowser,
WebDriver,
By,
WebView
WebView,
InputBox,
TextEditor,
BottomBarPanel,
MarkerType,
SettingsEditor
} from "vscode-extension-tester";
import { expect } from "chai";
import { initialize } from "../test/utils/utils";
Expand All @@ -28,6 +33,10 @@ import {
selectItem,
} from "./utils/utils";

import { constants } from "../utils/common/constants";
import * as path from "path";
import * as fsp from "fs/promises";

// Load environment variables
dotenv.config();
const CX_AUTHENTICATION_COMMAND = "ast-results.showAuth";
Expand All @@ -40,7 +49,7 @@ describe("Checkmarx VS Code Extension Tests", () => {
let bench: Workbench;
let driver: WebDriver;

it("Authentication: should authenticate using API key and verify button state", async function() {
it("Authentication: should authenticate using API key and verify button state", async function () {
this.timeout(120000);
console.log("Starting API key authentication test...");
bench = new Workbench();
Expand All @@ -64,7 +73,7 @@ describe("Checkmarx VS Code Extension Tests", () => {
// Find and select the API key radio button option
const radioButtons = await webview.findWebElements(By.css("input[type='radio']"));
console.log(`Found ${radioButtons.length} radio buttons`);

if (radioButtons.length >= 2) {
const apiKeyRadio = radioButtons[1];
await apiKeyRadio.click();
Expand All @@ -87,11 +96,11 @@ describe("Checkmarx VS Code Extension Tests", () => {
const state = await authButton.getAttribute("disabled");
return state !== "true";
}, 5000, "Auth button did not become enabled");

// Verify that the auth button is now enabled
disabledAttr = await authButton.getAttribute("disabled");
expect(disabledAttr).to.not.equal("true", "Auth button should be enabled after API key entry");

// Click the auth button
await authButton.click();
console.log("Clicked 'Sign in' button");
Expand Down Expand Up @@ -162,5 +171,63 @@ describe("Checkmarx VS Code Extension Tests", () => {
expect(branch).is.not.undefined;
});
});


// describe("OSS Scanner E2E Integration", () => {
// before(async function () {
// this.timeout(60000);
// // Enable OSS realtime scanner in settings
// console.log("Enabling OSS scanner for E2E tests...");
// const settingsEditor = await bench.openSettings();
// const ossCheckbox = await settingsEditor.findSetting(
// constants.activateOssRealtimeScanner,
// constants.ossRealtimeScanner
// );
// await ossCheckbox.setValue(true);
// console.log("OSS scanner enabled");

// // Close settings
// await new EditorView().closeAllEditors();
// });

// it("should scan package.json and detect security issues", async function () {
// this.timeout(220000);

// const packageJsonPath = path.join(__dirname, "menifastFiles", "package.json");

// await bench.executeCommand("workbench.view.explorer");
// await sleep(2000);

// const folderPath = path.join(__dirname, "menifastFiles");

// await bench.executeCommand("workbench.action.files.openFolder");
// const folderInput = await InputBox.create();
// await folderInput.setText(folderPath);
// await folderInput.confirm();
// await sleep(3000);

// await bench.executeCommand("workbench.action.files.openFile");
// const input = await InputBox.create();
// await input.setText(packageJsonPath);
// await input.confirm();

// await sleep(5000);

// const editorView = new EditorView();
// const editor = await editorView.openEditor("package.json") as TextEditor;
// expect(editor).to.not.be.undefined;

// await sleep(15000);
// const bottomBar = new BottomBarPanel();
// await bottomBar.toggle(true);

// const problemsView = await bottomBar.openProblemsView();

// await sleep(25000);

// const markers = await problemsView.getAllMarkers(MarkerType.Error);
// expect(markers.length).to.be.greaterThan(0, "Expected OSS scanner to find security issues");

// });
// });

});
217 changes: 217 additions & 0 deletions src/e2e/ossRealtimeScanner.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import dotenv from "dotenv";
import {
InputBox,
VSBrowser,
WebDriver,
Workbench,
EditorView,
TextEditor,
BottomBarPanel,
MarkerType,
SettingsEditor
} from "vscode-extension-tester";
import { expect } from "chai";
import { initialize } from "../test/utils/utils";
import {
CX_CLEAR,
} from "../test/utils/constants";
import {
waitForElementToAppear,
waitForInputBoxToOpen,
selectItem,
} from "./utils/utils";
import { constants } from "../utils/common/constants";
import * as path from "path";
import * as fsp from "fs/promises";

// Load environment variables
dotenv.config();

function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}

describe("OSS Scanner E2E Tests", () => {
let bench: Workbench;
let driver: WebDriver;
let editorView: EditorView;

before(async function () {
this.timeout(120000);
console.log("Starting OSS Scanner E2E tests setup...");
bench = new Workbench();
driver = VSBrowser.instance.driver;
editorView = new EditorView();

// Enable OSS realtime scanner in settings
console.log("Opening settings to enable OSS scanner...");
const settingsEditor = await bench.openSettings();
const ossCheckbox = await settingsEditor.findSetting(
constants.activateOssRealtimeScanner,
constants.ossRealtimeScanner
);
await ossCheckbox.setValue(true);
console.log("OSS scanner enabled in settings");

// Close settings by closing all editors
await editorView.closeAllEditors();

await bench.executeCommand("workbench.view.explorer");
await sleep(2000);

const folderPath = path.join(__dirname, "menifastFiles");

await bench.executeCommand("workbench.action.files.openFolder");
const folderInput = await InputBox.create();
await folderInput.setText(folderPath);
await folderInput.confirm();
await sleep(3000);


await initialize();
console.log("OSS Scanner E2E tests setup completed");
});

// after(async () => {
// console.log("Cleaning up OSS Scanner E2E tests...");
// await bench.executeCommand(CX_CLEAR);
// await editorView.closeAllEditors();
// });

describe("Real-time OSS Scanning E2E", () => {
it("should scan package.json file on open and show security diagnostics", async function () {
this.timeout(220000);

const packageJsonPath = path.join(__dirname, "menifastFiles", "package.json");

await bench.executeCommand("workbench.action.files.openFile");
const input = await InputBox.create();
await input.setText(packageJsonPath);
await input.confirm();

await sleep(5000);

const editorView = new EditorView();
const editor = await editorView.openEditor("package.json") as TextEditor;
expect(editor).to.not.be.undefined;

await sleep(15000);
const bottomBar = new BottomBarPanel();
await bottomBar.toggle(true);

const problemsView = await bottomBar.openProblemsView();

await sleep(25000);

const markers = await problemsView.getAllMarkers(MarkerType.Error);
expect(markers.length).to.be.greaterThan(0, "Expected OSS scanner to find security issues");

const maliciousMarkers = (
await Promise.all(markers.map(async (marker) => {
const text = await marker.getText();
return text.includes("Malicious package detected") ? marker : null;
}))
).filter(Boolean);

const scaCriticalVulnerabilityMarkers = (
await Promise.all(markers.map(async (marker) => {
const text = await marker.getText();
return text.includes("Critical-risk package")
}))
).filter(Boolean);

const scaHighVulnerabilityMarkers = (
await Promise.all(markers.map(async (marker) => {
const text = await marker.getText();
return text.includes("High-risk package")
}))
).filter(Boolean);
const scaMediumVulnerabilityMarkers = (
await Promise.all(markers.map(async (marker) => {
const text = await marker.getText();
return text.includes("Medium-risk package")
}))
).filter(Boolean);

expect(maliciousMarkers.length, "Expected to find malicious package markers").to.be.greaterThan(0);
expect(scaCriticalVulnerabilityMarkers.length, "Expected to find critical-risk package markers").to.be.greaterThan(0);
expect(scaHighVulnerabilityMarkers.length, "Expected to find high-risk package markers").to.be.greaterThan(0);
expect(scaMediumVulnerabilityMarkers.length, "Expected to find medium-risk package markers").to.be.greaterThan(0);

});


it("should scan file on content change and generate problems", async function () {
this.timeout(120000);
console.log("Starting dynamic content change scan test...");

const packageJsonPath = path.join(__dirname, "menifastFiles", "package.json");
const originalContent = await fsp.readFile(packageJsonPath, "utf8");
console.log("Original package.json content loaded");

await bench.executeCommand("workbench.action.files.openFile");
const input = await InputBox.create();
await input.setText(packageJsonPath);
await input.confirm();

const editor = await editorView.openEditor("package.json") as TextEditor;
expect(editor).to.not.be.undefined;

const bottomBar = new BottomBarPanel();
await bottomBar.toggle(true);
const problemsView = await bottomBar.openProblemsView();

try {
// Clear content to remove all issues
console.log("Clearing package.json content...");
await editor.setText(`{}`);
await sleep(3000);

let markers = await problemsView.getAllMarkers(MarkerType.Error);
console.log(`Markers after clearing content: ${markers.length}`);
expect(markers.length).to.equal(0, "Expected no markers with empty package.json");

// Restore original content with vulnerabilities
// console.log("Restoring original content with vulnerabilities...");
// await editor.setText(originalContent);
// await sleep(8000); // Give more time for scanner to process

// markers = await problemsView.getAllMarkers(MarkerType.Error);
// console.log(`Markers after restoring content: ${markers.length}`);

// // Debug: Log marker texts
// const markerTexts = await Promise.all(markers.map(async (marker) => {
// return await marker.getText();
// }));
// console.log("Marker texts after restore:", markerTexts);

// expect(markers.length).to.be.greaterThan(0, "Expected markers to appear after restoring vulnerable content");

// console.log("Dynamic content change scan test completed successfully");
} finally {
// Ensure we restore the original content
// await editor.setText(originalContent);
await sleep(1000);
}
});
});

describe("OSS Scanner Settings Verification", () => {
// it("should verify OSS scanner is enabled in settings", async function () {
// this.timeout(60000);
// console.log("Verifying OSS scanner settings...");

// const settingsEditor = await bench.openSettings();
// const ossCheckbox = await settingsEditor.findSetting(
// constants.activateOssRealtimeScanner,
// constants.ossRealtimeScanner
// );

// const isEnabled = await ossCheckbox.getValue();
// expect(isEnabled).to.be.true;
// console.log("OSS scanner is properly enabled in settings");

// await editorView.closeAllEditors();
// });
});
});
Loading
Loading