Skip to content

Add ui test for Oauth (AST-89331) #1080

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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions media/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
});

authButton.addEventListener("click", () => {
messageBox.style.display = "none";

vscode.postMessage({
command: "authenticate",
authMethod: document.querySelector('input[name="authMethod"]:checked')
Expand Down
1 change: 0 additions & 1 deletion src/cx/cx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ export class Cx implements CxPlatform {

async getAstConfiguration() {
const token = await this.context.secrets.get("authCredential");
console.log("Token from secrets:", token);

if (!token) {
return undefined;
Expand Down
1 change: 0 additions & 1 deletion src/cx/cxMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,6 @@ export class CxMock implements CxPlatform {

async getAstConfiguration() {
const token = await this.context.secrets.get("authCredential");
console.log("Token from secrets:", token);

if (!token) {
return undefined;
Expand Down
2 changes: 1 addition & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export async function activate(context: vscode.ExtensionContext) {
vscode.commands.registerCommand("ast-results.mockTokenTest", async () => {
const authService = AuthService.getInstance(context);
await authService.saveToken(context, "FAKE_TOKEN_FROM_TEST");
console.log(">> Mock token has been saved to secrets"); // שורת לוג
console.log(">> Mock token has been saved to secrets");
await authService.validateAndUpdateState();
});

Expand Down
24 changes: 14 additions & 10 deletions src/services/authService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,16 +182,20 @@ private async checkUrlExists(urlToCheck: string, isTenantCheck = false): Promise

try {
const server = await this.startLocalServer(config);
vscode.env.openExternal(vscode.Uri.parse(
`${config.authEndpoint}?` +
`client_id=${config.clientId}&` +
`redirect_uri=${encodeURIComponent(config.redirectUri)}&` +
`response_type=code&` +
`scope=${config.scope}&` +
`code_challenge=${config.codeChallenge}&` +
`code_challenge_method=S256`
));


const authUrl = `${config.authEndpoint}?` +
`client_id=${config.clientId}&` +
`redirect_uri=${encodeURIComponent(config.redirectUri)}&` +
`response_type=code&` +
`scope=${config.scope}&` +
`code_challenge=${config.codeChallenge}&` +
`code_challenge_method=S256`;

const opened = await vscode.env.openExternal(vscode.Uri.parse(authUrl));
if (!opened) {
server.close();
return "";
}
// Now we get both the code and response object
const { code, res } = await this.waitForCode(server);
const token = await this.getRefreshToken(code, config);
Expand Down
158 changes: 158 additions & 0 deletions src/test/12.oauthAuthentication.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import {
By,
EditorView,
VSBrowser,
WebDriver,
WebView,
Workbench
} from "vscode-extension-tester";
import { expect } from "chai";
import { retryTest, sleep } from "./utils/utils";

const CX_AUTHENTICATION_COMMAND = "ast-results.showAuth";

describe.skip("Checkmarx OAuth Authentication Tests", () => {
let bench: Workbench;
let driver: WebDriver;

before(async function () {
this.timeout(15000);
bench = new Workbench();
driver = VSBrowser.instance.driver;
});

after(async () => {
await bench.executeCommand("ast-results.mockTokenTest");
await sleep(3000);
await new EditorView().closeAllEditors();
});

it("should open OAuth authentication panel and verify logout/login flow", retryTest(async function () {
await bench.executeCommand(CX_AUTHENTICATION_COMMAND);
await sleep(5000);

const editorView = new EditorView();
await editorView.openEditor("Checkmarx One Authentication");

const webView = new WebView();
await webView.switchToFrame(10000);

let logoutElements = await webView.findWebElements(By.id("logoutButton"));
const isLoggedIn = logoutElements.length > 0 && await logoutElements[0].isDisplayed();

if (!isLoggedIn) {
await webView.switchBack();
await bench.executeCommand("ast-results.mockTokenTest");
await sleep(3000);
await new EditorView().closeAllEditors();
await bench.executeCommand(CX_AUTHENTICATION_COMMAND);
await sleep(3000);
await new EditorView().openEditor("Checkmarx One Authentication");
await webView.switchToFrame(5000);
logoutElements = await webView.findWebElements(By.id("logoutButton"));
}

logoutElements = await webView.findWebElements(By.id("logoutButton"));
if (logoutElements.length > 0 && await logoutElements[0].isDisplayed()) {
await webView.switchBack();
await webView.switchToFrame(5000);
await logoutElements[0].click();
await webView.switchBack();
await sleep(3000);
await handleLogoutConfirmation(driver);
await webView.switchToFrame(5000);
}

const loginForm = await webView.findWebElements(By.id("loginForm"));
expect(loginForm.length).to.be.greaterThan(0, "Login form should be visible when logged out");
}, 3));

it("should verify radio buttons exist", retryTest(async function () {
const webView = new WebView();
await webView.switchToFrame(10000);

const radioButtons = await webView.findWebElements(By.css("input[type='radio']"));
expect(radioButtons.length).to.be.at.least(2, "Should have at least 2 radio buttons (OAuth and API Key)");

await webView.switchBack();
}, 3));

it("should verify OAuth form exists", retryTest(async function () {
const webView = new WebView();
await webView.switchToFrame(10000);

const oauthRadio = await webView.findWebElement(By.css("input[name='authMethod'][value='oauth']"));
await driver.executeScript("arguments[0].click();", oauthRadio);
await sleep(1000);

const oauthForm = await webView.findWebElement(By.id("oauthForm"));
expect(oauthForm).to.not.be.undefined;

await webView.switchBack();
}, 3));

it("should verify OAuth form text labels", retryTest(async function () {
const webView = new WebView();
await webView.switchToFrame(10000);

const oauthForm = await webView.findWebElement(By.id("oauthForm"));
const oauthFormText = await oauthForm.getText();

expect(oauthFormText).to.include("Checkmarx One Base URL:", "Base URL label should be present in OAuth form");
expect(oauthFormText).to.include("Tenant Name:", "Tenant Name label should be present in OAuth form");

await webView.switchBack();
}, 3));

it("should verify OAuth button disabled state", retryTest(async function () {
const webView = new WebView();
await webView.switchToFrame(10000);

const authButton = await webView.findWebElement(By.id("authButton"));
const disabledAttr = await authButton.getAttribute("disabled");
expect(disabledAttr).to.equal("true", "Auth button should be disabled when OAuth fields are empty");

await webView.switchBack();
}, 3));

it("should verify API Key form text labels", retryTest(async function () {
const webView = new WebView();
await webView.switchToFrame(10000);

const apiKeyRadio = await webView.findWebElement(By.css("input[name='authMethod'][value='apiKey']"));
await driver.executeScript("arguments[0].click();", apiKeyRadio);
await sleep(1000);

const apiKeyForm = await webView.findWebElement(By.id("apiKeyForm"));
const apiKeyFormText = await apiKeyForm.getText();

expect(apiKeyFormText).to.include("Checkmarx One API Key:", "API Key label should be present in API Key form");

await webView.switchBack();
}, 3));

it("should verify API Key button disabled state", retryTest(async function () {
const webView = new WebView();
await webView.switchToFrame(10000);

const authButton = await webView.findWebElement(By.id("authButton"));
const disabledAttr = await authButton.getAttribute("disabled");
expect(disabledAttr).to.equal("true", "Auth button should be disabled when API Key field is empty");

await webView.switchBack();
}, 3));

async function handleLogoutConfirmation(driver) {
const notifications = await driver.findElements(By.className("notification-toast"));
for (const notification of notifications) {
const notificationText = await notification.getText();
if (notificationText.includes("Are you sure you want to log out?")) {
const yesButton = await notification.findElement(By.css(".monaco-button"));
await yesButton.click();
await sleep(2000);
return true;
}
}
return false;
}
});
2 changes: 1 addition & 1 deletion src/webview/authenticationWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,4 +291,4 @@ export class AuthenticationWebview {
}
}
}
}
}
Loading