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
10 changes: 5 additions & 5 deletions .github/workflows/ui-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ jobs:
with:
fetch-depth: '10'
path: apim-apps
- name: Set up JDK 11
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: 11
java-version: 21
distribution: 'temurin'
- uses: actions/setup-node@v4
with:
Expand Down Expand Up @@ -73,13 +73,13 @@ jobs:
nc -zv localhost 9443
- uses: actions/setup-node@v4
with:
node-version: '18'
node-version: '22'
- name: Cypress run
uses: cypress-io/github-action@v4
uses: cypress-io/github-action@v7
with:
record: false
working-directory: 'apim-apps/tests'
spec: '**/*.spec.js'
spec: 'cypress/e2e/**/*.cy.js'
- name: Upload Screenshots
uses: actions/upload-artifact@v4
if: failure()
Expand Down
42 changes: 42 additions & 0 deletions tests/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const { defineConfig } = require('cypress')
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

Missing copyright header. The file should include the Apache 2.0 license header consistent with other files in the codebase (see tests/package.json or test files for reference).

Copilot uses AI. Check for mistakes.

module.exports = defineConfig({
chromeWebSecurity: false,
pageLoadTimeout: 100000,
defaultCommandTimeout: 100000,
screenshotsFolder: 'cypress/screenshots',
screenshotOnRunFailure: true,
reporter: 'cypress-multi-reporters',
reporterOptions: {
inlineAssets: true,
reporterEnabled: 'cypress-mochawesome-reporter, mocha-junit-reporter',
mochaJunitReporterReporterOptions: {
mochaFile: 'cypress/reports/junit/results-[hash].xml',
},
cypressMochawesomeReporterReporterOptions: {
charts: true,
reportPageTitle: 'custom-title',
},
},
Comment on lines +10 to +20
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

inlineAssets is misplaced at the top level of reporterOptions and will be silently ignored by cypress-mochawesome-reporter.

When using cypress-multi-reporters, each sub-reporter's options must be nested under its corresponding <camelCasedPackageName>ReporterOptions key. inlineAssets is a cypress-mochawesome-reporter option and belongs inside cypressMochawesomeReporterReporterOptions, not at the root of reporterOptions.

🐛 Proposed fix
  reporterOptions: {
-   inlineAssets: true,
    reporterEnabled: 'cypress-mochawesome-reporter, mocha-junit-reporter',
    mochaJunitReporterReporterOptions: {
      mochaFile: 'cypress/reports/junit/results-[hash].xml',
    },
    cypressMochawesomeReporterReporterOptions: {
      charts: true,
      reportPageTitle: 'custom-title',
+     inlineAssets: true,
    },
  },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/cypress.config.js` around lines 12 - 22, Move the misplaced
inlineAssets key from the top level of reporterOptions into the
cypressMochawesomeReporterReporterOptions block so the
cypress-mochawesome-reporter actually receives it; update the reporterOptions
object (referencing reporterOptions, inlineAssets and
cypressMochawesomeReporterReporterOptions) to nest inlineAssets under
cypressMochawesomeReporterReporterOptions rather than at the root.

video: false,
scrollBehavior: 'nearest',
retries: {
runMode: 2,
openMode: 0,
},
env: {
largeTimeout: 100000,
},
e2e: {
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
excludeSpecPattern: [
'**/externalDevPortals/**/*.cy.js',
'**/06-solace-broker-integration.cy.js',
'**/*.cy.skip.js',
],
Comment on lines +35 to +39
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

'**/*.cy.skip.js' in excludeSpecPattern is a dead pattern and will never match any discovered spec.

The specPattern is cypress/e2e/**/*.cy.{js,jsx,ts,tsx}, which only discovers files whose name ends in exactly .cy.js, .cy.jsx, .cy.ts, or .cy.tsx. A file named foo.cy.skip.js ends in .cy.skip.js, which does not satisfy any of those suffixes, so it is never picked up by the spec scanner in the first place. The exclude rule is therefore a no-op and should be removed (or the convention should be reconsidered—e.g., renaming skipped tests to *.cy.js.skip instead).

♻️ Proposed fix
    excludeSpecPattern: [
      '**/externalDevPortals/**/*.cy.js',
      '**/06-solace-broker-integration.cy.js',
-     '**/*.cy.skip.js',
    ],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
excludeSpecPattern: [
'**/externalDevPortals/**/*.cy.js',
'**/06-solace-broker-integration.cy.js',
'**/*.cy.skip.js',
],
excludeSpecPattern: [
'**/externalDevPortals/**/*.cy.js',
'**/06-solace-broker-integration.cy.js',
],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/cypress.config.js` around lines 34 - 38, The excludeSpecPattern entry
'**/*.cy.skip.js' is a dead pattern because specPattern only discovers files
ending exactly in .cy.{js,jsx,ts,tsx}; remove the redundant '**/*.cy.skip.js'
from the excludeSpecPattern array in tests/cypress.config.js (or alternatively
standardize skipped-test filenames to match the discovered suffixes, e.g.,
rename to *.cy.js.skip and adjust specPattern accordingly), ensuring you update
the excludeSpecPattern array and any test filenames consistently; look for the
excludeSpecPattern and specPattern identifiers to make the change.

baseUrl: 'https://localhost:9443',
},
})
35 changes: 0 additions & 35 deletions tests/cypress.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe("Add custom throttle policies", () => {
}, () => {
const policyName = '5reqPerMin';
const secondDesc = 'For an Admin users allow 5 requests per minute';
cy.get('[data-testid="Custom Policies-child-link"]', {timeout: Cypress.config().largeTimeout}).click();
cy.get('[data-testid="Custom Policies-child-link"]', {timeout: Cypress.env('largeTimeout')}).click();
cy.get('[data-testid="throttling-custom-add-button"]').contains('Define Policy').click();
cy.get('input[name="policyName"]').type(policyName);
cy.get('input[name="description"]').type('Allow 5 requests per minute for an Admin user');
Expand All @@ -46,7 +46,7 @@ describe("Add custom throttle policies", () => {

cy.intercept('GET', '**/throttling/policies/custom').as('getCustomPolicies');
cy.get('[data-testid="throttling-custom-save-button"]').contains('Edit').click();
cy.wait('@getCustomPolicies', {timeout: Cypress.config().largeTimeout}).then(() => {
cy.wait('@getCustomPolicies', {timeout: Cypress.env('largeTimeout')}).then(() => {
cy.get('td').contains(secondDesc).should('exist');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe("Add API Categories and assign via publisher portal", () => {
const category = Utils.generateName();
const categoryDescription = 'Weather related apis';

cy.get('[data-testid="API Categories"]', { timeout: Cypress.config().largeTimeout }).click();
cy.get('[data-testid="API Categories"]', { timeout: Cypress.env('largeTimeout') }).click();
cy.get('[data-testid="form-dialog-base-trigger-btn"]').contains('Add API Category').click();
cy.get('input[name="name"]').type(category);
cy.get('textarea[name="description"]').type(categoryDescription);
Expand All @@ -48,7 +48,7 @@ describe("Add API Categories and assign via publisher portal", () => {
Utils.addAPI({}).then((apiId) => {
testApiId = apiId;
cy.visit(`/publisher/apis/${apiId}/configuration`);
cy.get('#APICategories-autocomplete', { timeout: Cypress.config().largeTimeout }).click();
cy.get('#APICategories-autocomplete', { timeout: Cypress.env('largeTimeout') }).click();
cy.get('li').contains(category).click();
cy.get('#design-config-save-btn').click();
cy.contains('API updated successfully').should('be.visible');
Expand All @@ -61,14 +61,14 @@ describe("Add API Categories and assign via publisher portal", () => {
// Delete
cy.visit(`/admin/settings/api-categories`);
cy.wait(7000);
cy.get('[data-testid="MuiDataTableBodyCell-4-0"] > div > div > span:nth-child(2)', { timeout: Cypress.config().largeTimeout })
cy.get('[data-testid="MuiDataTableBodyCell-4-0"] > div > div > span:nth-child(2)', { timeout: Cypress.env('largeTimeout') })
.should('be.visible')
.click();
cy.get('[data-testid="form-dialog-base-save-btn"]').contains("Delete")
.should('be.visible')
.click();
cy.contains('API Category deleted successfully').should('be.visible');
//cy.get('div[role="status"]', {timeout: Cypress.config().largeTimeout}).should('have.text', 'API Category deleted successfully');
//cy.get('div[role="status"]', {timeout: Cypress.env('largeTimeout')}).should('have.text', 'API Category deleted successfully');
});
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ describe("Add key manager", () => {
cy.get(`#${km}`).should('not.exist');

cy.visit(`/devportal/applications?tenant=carbon.super`);
cy.get(`#itest-application-list-table td a`, {timeout: Cypress.config().largeTimeout}).contains(appName).click();
cy.get(`#itest-application-list-table td a`, {timeout: Cypress.env('largeTimeout')}).contains(appName).click();
cy.get('#production-keys').click();
cy.get(`#${km}`).should('not.exist');
cy.get('#sandbox-keys').click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe("Anonymous view apis", () => {
let remainingAttempts = 15;
let attemptCount = 0;
for (; attemptCount < remainingAttempts; attemptCount++) {
let $apis = Cypress.$('a', apiName, { timeout: Cypress.config().largeTimeout });
let $apis = Cypress.$('a', apiName, { timeout: Cypress.env('largeTimeout') });
if ($apis.length) {
// At least one with api name was found.
// Return a jQuery object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,66 +50,66 @@ describe("Self SignUp", () => {
const internalSubscriberRole = 'Internal/subscriber';
const internalTestRole = 'Internal/testRole';
const selfSignupDisabledConfigJson = JSON.parse(JSON.stringify(tenantConfigJson));
delete selfSignupDisabledConfigJson.SelfSignUp;
selfSignupDisabledConfigJson.SelfSignUp = { "SignUpRoles": [] };
const customUserRoleAddedConfigJson = JSON.parse(JSON.stringify(tenantConfigJson));
customUserRoleAddedConfigJson.SelfSignUp.SignUpRoles.push(internalTestRole);

it.only("Test - Default self-signup behaviour of the super tenant", () => {
it("Test - Default self-signup behaviour of the super tenant", () => {
cy.addNewUserUsingSelfSignUp(superTenant1Username, password, firstName, lastName,
getSuperTenantEmail(superTenant1Username), superTenant);
cy.addExistingUserUsingSelfSignUp(superTenant1Username, superTenant);
cy.portalLogin(superTenant1Username, password, devPortal, superTenant);
cy.logoutFromDevportal();
});

it.only("Test - Default self-signup behaviour of the wso2 tenant", () => {
it("Test - Default self-signup behaviour of the wso2 tenant", () => {
cy.addNewUserUsingSelfSignUp(Utils.getTenantUser(tenant1Username, testTenant), password, firstName, lastName,
Utils.getTenantUser(tenant1Username, testTenant), testTenant);
cy.addExistingUserUsingSelfSignUp(Utils.getTenantUser(tenant1Username, testTenant), testTenant);
cy.portalLogin(Utils.getTenantUser(tenant1Username, testTenant), password, devPortal, testTenant);
cy.logoutFromDevportal();
});

it.only("Test - Login to the devPortal using incorrect user credentials", () => {
it("Test - Login to the devPortal using incorrect user credentials", () => {
cy.portalLoginUsingIncorrectUserCredentials(incorrectUsername, incorrectPassword, devPortal, testTenant);
});

it.only("Test - Login to the publisher portal using incorrect user credentials", () => {
it("Test - Login to the publisher portal using incorrect user credentials", () => {
cy.portalLoginUsingIncorrectUserCredentials(incorrectUsername, incorrectPassword, publisher, superTenant);
});

it.only("Test - Login to the admin portal using incorrect user credentials", () => {
it("Test - Login to the admin portal using incorrect user credentials", () => {
cy.portalLoginUsingIncorrectUserCredentials(incorrectUsername, incorrectPassword, adminPortal, superTenant);
});

it.only("Test - Login to the carbon using incorrect user credentials", () => {
it("Test - Login to the carbon using incorrect user credentials", () => {
cy.carbonLogin(incorrectUsername, incorrectPassword);
cy.contains('Login failed! Please recheck the username and password and try again.').should('exist');
});

it.only("Test - Login to the publisher using newly created user(superTenant1) credentials", () => {
it("Test - Login to the publisher using newly created user(superTenant1) credentials", () => {
cy.portalLogin(superTenant1Username, password, publisher, superTenant);
cy.contains('Error 403 : Forbidden').should('exist');
cy.contains('The server could not verify that you are authorized to access the requested resource.').should('exist');
cy.logoutFromPublisher();
});

it.only("Test - Login to the admin portal using newly created user(superTenant1) credentials", () => {
it("Test - Login to the admin portal using newly created user(superTenant1) credentials", () => {
cy.portalLogin(superTenant1Username, password, adminPortal, superTenant);
cy.contains('Error 403 : Forbidden').should('exist');
cy.contains('The server could not verify that you are authorized to access the requested resource.').should('exist');
cy.logoutFromAdminPortal();
});

it.only("Test - Login to the carbon using newly created user(superTenant1) credentials", () => {
it("Test - Login to the carbon using newly created user(superTenant1) credentials", () => {
cy.carbonLogin(superTenant1Username, password);
cy.get('#region1_dashboard_main_menu').should('not.exist');
cy.get('#region3_registry_menu').should('not.exist');
cy.get('#region3_metadata_menu').should('not.exist');
cy.carbonLogout();
});

it.only("Test - Remove self signup config from the advance configuration and create a new user for the super tenant", () => {
it("Test - Remove self signup config from the advance configuration and create a new user for the super tenant", () => {
cy.updateTenantConfig(carbonUsername, carbonPassword, superTenant, selfSignupDisabledConfigJson);
cy.addNewUserUsingSelfSignUp(superTenant2Username, password, firstName, lastName,
getSuperTenantEmail(superTenant2Username), superTenant);
Expand All @@ -119,7 +119,7 @@ describe("Self SignUp", () => {
cy.contains('Logout').click();
});

it.only("Test - Remove self signup config from the advance configuration and create a new user for the wso2 tenant", () => {
it("Test - Remove self signup config from the advance configuration and create a new user for the wso2 tenant", () => {
cy.updateTenantConfig(tenantAdminUsername, tenantAdminPassword, testTenant, selfSignupDisabledConfigJson);
cy.addNewUserUsingSelfSignUp(Utils.getTenantUser(tenant2Username, testTenant), password, firstName, lastName,
Utils.getTenantUser(tenant2Username, testTenant), testTenant);
Expand All @@ -129,7 +129,7 @@ describe("Self SignUp", () => {
cy.contains('Logout').click();
});

it.only("Test - Disable self signup from the carbon portal for the super tenant", () => {
it("Test - Disable self signup from the carbon portal for the super tenant", () => {
cy.disableSelfSignUpInCarbonPortal(carbonUsername, carbonPassword, superTenant);
cy.visit(`${Utils.getAppOrigin()}/devportal/apis?tenant=${superTenant}`);
cy.get('#itest-devportal-sign-in').click({ force: true });
Expand All @@ -139,7 +139,7 @@ describe("Self SignUp", () => {
cy.contains(`Self registration is disabled for tenant - ${superTenant}`).should('exist');
});

it.only("Test - Disable self signup from the carbon portal for the wso2 tenant", () => {
it("Test - Disable self signup from the carbon portal for the wso2 tenant", () => {
cy.disableSelfSignUpInCarbonPortal(tenantAdminUsername, tenantAdminPassword, testTenant);
cy.visit(`${Utils.getAppOrigin()}/devportal/apis?tenant=${testTenant}`);
cy.get('#itest-devportal-sign-in').click({ force: true });
Expand All @@ -149,7 +149,7 @@ describe("Self SignUp", () => {
cy.contains(`Self registration is disabled for tenant - ${testTenant}`).should('exist');
});

it.only("Test - Enable self signup back for the super tenant", () => {
it("Test - Enable self signup back for the super tenant", () => {
cy.updateTenantConfig(carbonUsername, carbonPassword, superTenant, tenantConfigJson);
cy.enableSelfSignUpInCarbonPortal(carbonUsername, carbonPassword, superTenant);
cy.addNewUserUsingSelfSignUp(superTenant4Username, password, firstName, lastName,
Expand All @@ -158,7 +158,7 @@ describe("Self SignUp", () => {
cy.logoutFromDevportal();
});

it.only("Test - Enable self signup back for the wso2 tenant", () => {
it("Test - Enable self signup back for the wso2 tenant", () => {
cy.updateTenantConfig(tenantAdminUsername, tenantAdminPassword, testTenant, tenantConfigJson);
cy.enableSelfSignUpInCarbonPortal(tenantAdminUsername, tenantAdminPassword, testTenant);
cy.addNewUserUsingSelfSignUp(Utils.getTenantUser(tenant4Username, testTenant), password, firstName, lastName,
Expand All @@ -167,7 +167,7 @@ describe("Self SignUp", () => {
cy.logoutFromDevportal();
});

it.only("Test - Assign custom user roles to a super tenant user", () => {
it("Test - Assign custom user roles to a super tenant user", () => {
cy.carbonLogin(carbonUsername, carbonPassword);
cy.addNewRole(userRole, domain);
cy.carbonLogout();
Expand All @@ -178,7 +178,7 @@ describe("Self SignUp", () => {
[internalSubscriberRole, internalTestRole]);
});

it.only("Test - Assign custom user roles to a tenant user", () => {
it("Test - Assign custom user roles to a tenant user", () => {
cy.carbonLogin(tenantAdminUsername, tenantAdminPassword);
cy.addNewRole(userRole, domain);
cy.carbonLogout();
Expand All @@ -189,7 +189,7 @@ describe("Self SignUp", () => {
[internalSubscriberRole, internalTestRole]);
});

it.only("Test - Create a user for a unregistered tenant", () => {
it("Test - Create a user for a unregistered tenant", () => {
cy.visit(`${Utils.getAppOrigin()}/devportal/apis?tenant=${testTenant}`);
cy.get('#itest-devportal-sign-in').click({ force: true });
cy.get('#registerLink').click();
Expand All @@ -199,15 +199,21 @@ describe("Self SignUp", () => {
});

after(function () {
// Reset tenant configs first so self-signup no longer depends on Internal/testRole.
cy.updateTenantConfig(carbonUsername, carbonPassword, superTenant, tenantConfigJson);
cy.enableSelfSignUpInCarbonPortal(carbonUsername, carbonPassword, superTenant);
cy.updateTenantConfig(tenantAdminUsername, tenantAdminPassword, testTenant, tenantConfigJson);
cy.enableSelfSignUpInCarbonPortal(tenantAdminUsername, tenantAdminPassword, testTenant);

cy.carbonLogin(carbonUsername, carbonPassword);
// delete all the created users for super tenant
cy.visit(`${Utils.getAppOrigin()}/carbon/user/user-mgt.jsp`);
cy.deleteUser(superTenant1Username);
cy.deleteUser(superTenant2Username);
cy.deleteUser(superTenant4Username);
cy.deleteUser(superTenant5Username);
// Remove created user roles
cy.deleteRole(internalTestRole);
// Remove created user role
cy.searchAndDeleteRoleIfExist(internalTestRole);
cy.carbonLogout();

cy.carbonLogin(tenantAdminUsername, tenantAdminPassword);
Expand All @@ -217,15 +223,8 @@ describe("Self SignUp", () => {
cy.deleteUser(tenant2Username);
cy.deleteUser(tenant4Username);
cy.deleteUser(tenant5Username);
// Remove created user roles
cy.deleteRole(internalTestRole);
// Remove created user role
cy.searchAndDeleteRoleIfExist(internalTestRole);
cy.carbonLogout();

// Reset all the configs back to ensure default behaviour
cy.updateTenantConfig(carbonUsername, carbonPassword, superTenant, tenantConfigJson);
cy.enableSelfSignUpInCarbonPortal(carbonUsername, carbonPassword, superTenant);

cy.updateTenantConfig(tenantAdminUsername, tenantAdminPassword, testTenant, tenantConfigJson);
cy.enableSelfSignUpInCarbonPortal(tenantAdminUsername, tenantAdminPassword, testTenant);
})
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe("Change the password from devportal", () => {
it.only("Change the password from devportal", () => {
cy.carbonLogin(carbonUsername, carbonPassword);
cy.addNewUser(username, ["Internal/subscriber"], password);
cy.get(".ui-dialog-buttonset", { timeout: Cypress.config().largeTimeout });
cy.get(".ui-dialog-buttonset", { timeout: Cypress.env('largeTimeout') });
cy.get("button").contains("OK").click();
cy.get("#userTable").contains("td", "newuser").should("exist");
cy.carbonLogout();
Expand All @@ -52,7 +52,7 @@ describe("Change the password from devportal", () => {
cy.get("input#repeated-new-password").click();
cy.get("input#repeated-new-password").type(newPassword);

cy.get("[data-testid='change-password-save-button']").debug().contains("Save").click();
cy.get("[data-testid='change-password-save-button']").contains("Save").click();

cy.logoutFromDevportal();
devportalComonPage.waitUntillDevportalLoaderSpinnerExit();
Expand Down
Loading