Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
667 changes: 285 additions & 382 deletions web/cypress/configure-env.sh

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion web/cypress/e2e/incidents/00.coo_incidents_e2e.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('BVT: Incidents - e2e', { tags: ['@smoke', '@slow', '@incidents', '@e2e
let currentAlertName: string;

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });

cy.cleanupIncidentPrometheusRules();

Expand Down
2 changes: 1 addition & 1 deletion web/cypress/e2e/incidents/01.incidents.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const ALERT_DESC = 'This is an alert meant to ensure that the entire alerting pi
const ALERT_SUMMARY = 'An alert that should always be firing to certify that Alertmanager is working properly.'
describe('BVT: Incidents - UI', { tags: ['@smoke', '@incidents'] }, () => {
before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
});


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const MP = {
describe('Incidents - Mocking Examples', { tags: ['@demo', '@incidents'] }, () => {

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const MP = {
describe('Regression: Incidents Filtering', { tags: ['@incidents'] }, () => {

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const MP = {
describe('Regression: Charts UI - Comprehensive', { tags: ['@incidents'] }, () => {

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });

});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('Regression: Time-Based Alert Resolution (E2E with Firing Alerts)', { t
let currentAlertName: string;

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });

cy.log('Create or reuse firing alert for testing');
cy.createKubePodCrashLoopingAlert('TimeBasedResolution2').then((alertName) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const MP = {
describe('Regression: Silences Not Applied Correctly', { tags: ['@incidents'] }, () => {

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const MP = {
describe('Regression: Redux State Management', { tags: ['@incidents', '@incidents-redux'] }, () => {

before(() => {
cy.beforeBlockCOO(MCP, MP);
cy.beforeBlockCOO(MCP, MP, { dashboards: false, troubleshootingPanel: false });
});

beforeEach(() => {
Expand Down
134 changes: 132 additions & 2 deletions web/cypress/support/commands/auth-commands.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { nav } from '../../views/nav';
import { guidedTour } from '../../views/tour';



export { };
declare global {
namespace Cypress {
Expand All @@ -22,6 +20,138 @@ declare global {
}
}

// ── Auth orchestration (RBAC + OAuth discovery + login) ────────────
// Moved from operator-commands.ts so all auth concerns live in one file.

export const operatorAuthUtils = {
performLoginAndAuth(useSession: boolean): void {
if (`${Cypress.env('LOGIN_USERNAME')}` === 'kubeadmin') {
cy.adminCLI(
`oc adm policy add-cluster-role-to-user cluster-admin ${Cypress.env('LOGIN_USERNAME')}`,
);
} else {
cy.adminCLI(`oc project openshift-monitoring`);
cy.adminCLI(
`oc adm policy add-role-to-user monitoring-edit ${Cypress.env('LOGIN_USERNAME')} -n openshift-monitoring`,
);
cy.adminCLI(
`oc adm policy add-role-to-user monitoring-alertmanager-edit --role-namespace openshift-monitoring ${Cypress.env('LOGIN_USERNAME')}`,
);
cy.adminCLI(
`oc adm policy add-role-to-user view ${Cypress.env('LOGIN_USERNAME')} -n openshift-monitoring`,
);
cy.adminCLI(`oc project default`);
cy.adminCLI(
`oc adm policy add-role-to-user monitoring-edit ${Cypress.env('LOGIN_USERNAME')} -n default`,
);
cy.adminCLI(
`oc adm policy add-role-to-user monitoring-alertmanager-edit --role-namespace default ${Cypress.env('LOGIN_USERNAME')}`,
);
cy.adminCLI(
`oc adm policy add-role-to-user view ${Cypress.env('LOGIN_USERNAME')} -n default`,
);
}
cy.exec(
`oc get oauthclient openshift-browser-client -o go-template --template="{{index .redirectURIs 0}}" --kubeconfig ${Cypress.env('KUBECONFIG_PATH')}`,
).then((result) => {
if (result.stderr === '') {
const oauth = result.stdout;
const oauthurl = new URL(oauth);
const oauthorigin = oauthurl.origin;
cy.log(oauthorigin);
cy.wrap(oauthorigin as string).as('oauthorigin');
} else {
throw new Error(`Execution of oc get oauthclient failed
Exit code: ${result.code}
Stdout:\n${result.stdout}
Stderr:\n${result.stderr}`);
Comment on lines +57 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use exit code to detect oc success, not empty stderr.

Relying on stderr === '' can false-fail valid executions (warnings). Use result.code === 0 and parse trimmed stdout.

♻️ Suggested fix
-      if (result.stderr === '') {
-        const oauth = result.stdout;
+      if (result.code === 0) {
+        const oauth = result.stdout.trim();
         const oauthurl = new URL(oauth);
         const oauthorigin = oauthurl.origin;
         cy.log(oauthorigin);
         cy.wrap(oauthorigin as string).as('oauthorigin');
       } else {
         throw new Error(`Execution of oc get oauthclient failed
           Exit code: ${result.code}
           Stdout:\n${result.stdout}
           Stderr:\n${result.stderr}`);
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/cypress/support/commands/auth-commands.ts` around lines 57 - 67, Replace
the success check that currently uses result.stderr === '' with a proper
exit-code check: test that result.code === 0 (success), then parse and trim
result.stdout before building the URL (use const oauth = result.stdout.trim()),
construct the URL (oauthurl) and derive oauthorigin as before; otherwise throw
the Error including result.code, result.stdout and result.stderr as currently
done. Ensure you update the block that assigns oauth, oauthurl and oauthorigin
to use the trimmed stdout and the success condition on result.code.

}
});
cy.get('@oauthorigin').then((oauthorigin) => {
if (useSession) {
cy.login(
Cypress.env('LOGIN_IDP'),
Cypress.env('LOGIN_USERNAME'),
Cypress.env('LOGIN_PASSWORD'),
oauthorigin as unknown as string,
);
} else {
cy.loginNoSession(
Cypress.env('LOGIN_IDP'),
Cypress.env('LOGIN_USERNAME'),
Cypress.env('LOGIN_PASSWORD'),
oauthorigin as unknown as string,
);
}
});
},

loginAndAuth(): void {
cy.log('Before block');
operatorAuthUtils.performLoginAndAuth(true);
},

loginAndAuthNoSession(): void {
cy.log('Before block (no session)');
operatorAuthUtils.performLoginAndAuth(false);
},

generateCOOSessionKey(
MCP: { namespace: string; operatorName: string; packageName: string },
MP: { namespace: string; operatorName: string },
): string[] {
const baseKey = [
Cypress.env('LOGIN_IDP'),
Cypress.env('LOGIN_USERNAME'),
MCP.namespace,
MCP.operatorName,
MCP.packageName,
MP.namespace,
MP.operatorName,
];
const envVars = [
Cypress.env('SKIP_ALL_INSTALL'),
Cypress.env('SKIP_COO_INSTALL'),
Cypress.env('COO_UI_INSTALL'),
Cypress.env('KONFLUX_COO_BUNDLE_IMAGE'),
Cypress.env('CUSTOM_COO_BUNDLE_IMAGE'),
Cypress.env('FBC_STAGE_COO_IMAGE'),
Cypress.env('MP_IMAGE'),
Cypress.env('MCP_CONSOLE_IMAGE'),
Cypress.env('CHA_IMAGE'),
];
return [...baseKey, ...envVars.map((v) => v || '')];
},

generateMPSessionKey(MP: { namespace: string; operatorName: string }): string[] {
const baseKey = [
Cypress.env('LOGIN_IDP'),
Cypress.env('LOGIN_USERNAME'),
MP.namespace,
MP.operatorName,
];
const envVars = [
Cypress.env('SKIP_ALL_INSTALL'),
Cypress.env('MP_IMAGE'),
];
return [...baseKey, ...envVars.map((v) => v || '')];
},

generateKBVSessionKey(KBV: { namespace: string; packageName: string }): string[] {
const baseKey = [
Cypress.env('LOGIN_IDP'),
Cypress.env('LOGIN_USERNAME'),
KBV.namespace,
KBV.packageName,
];
const envVars = [
Cypress.env('SKIP_KBV_INSTALL'),
Cypress.env('KBV_UI_INSTALL'),
];
return [...baseKey, ...envVars.map((v) => v || '')];
},
};


// Core login function (used by both session and non-session versions)
function performLogin(
Expand Down
Loading