Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a098ee0
Update ROR settings configuration in E2E tests
Dzuming Sep 2, 2026
49495bb
Implement custom clipboard capture for Cypress tests
Dzuming Sep 2, 2026
ca4eee8
Add retry logic to E2E HTTP requests
Dzuming Sep 2, 2026
bb78c97
Improve Kibana API client robustness and type safety
Dzuming Sep 2, 2026
b518669
Fix flaky E2E tests by updating wait commands and timeouts
Dzuming Sep 2, 2026
2f72397
Update delete space helper to use waitForResponse
Dzuming Sep 2, 2026
4d47e05
Refactor E2E test configuration files
Dzuming Sep 2, 2026
4b7b218
Refactor Kibana-config E2E tests and improve test stability
Dzuming Sep 2, 2026
9b77dd4
Migrate ReadonlyREST settings E2E tests
Dzuming Sep 2, 2026
b12a52c
Add E2E test for hiding apps in search results
Dzuming Sep 2, 2026
27824fb
Update default settings files and remove search tests
Dzuming Sep 2, 2026
b243fb2
Update e2e tests to use Settings page object and confirm saves
Dzuming Sep 2, 2026
4902f38
Update E2E test configuration and user credentials
Dzuming Sep 2, 2026
f03aa75
Remove unused default settings fixture
Dzuming Sep 2, 2026
c687fb1
Skip flaky test in elk-ror and update chunk load error suppression
Dzuming Sep 2, 2026
75e864e
Fix JSON syntax for whitelistedPaths in E2E test fixture
Dzuming Sep 2, 2026
929b8c8
Remove custom JS injection from ROR Kibana settings
Dzuming Sep 2, 2026
63a10a5
Refactor RorApiClient to handle idempotent settings updates
Dzuming Sep 3, 2026
f7e589c
Add hide_apps to default readonlyrest settings fixture
Dzuming Sep 3, 2026
6378950
Merge branch 'develop' into epic/RORDEV-1524-Keep-ROR-Kibana-and-ES-p…
Dzuming Sep 11, 2026
c17014e
Merge branch 'develop' into epic/RORDEV-1524-Keep-ROR-Kibana-and-ES-p…
Dzuming Sep 14, 2026
8b83b7f
Merge branch 'develop' into epic/RORDEV-1524-Keep-ROR-Kibana-and-ES-p…
Dzuming Sep 19, 2026
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 e2e-tests/cypress/e2e/Allowed-api-paths.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ const apiOnlyInternalUser = 'api_only_internal_user:dev';
const apiOnlyRorUser = 'api_only_ror_user:dev';

describe('allowed_api_paths enforcement for api_only users', () => {
before(() => rorApiClient.configureRorIndexMainSettings('allowedApiPathsSettings.yaml'));
after(() => rorApiClient.configureRorIndexMainSettings('defaultSettings.yaml'));
before(() => rorApiClient.configureRorIndexMainSettingsFromFixture('allowedApiPathsSettings.yaml'));
after(() => rorApiClient.configureRorIndexMainSettingsFromFixture('defaultReadonlyRestEsAndKbnSettings.yaml'));

describe('exact /api/ path', () => {
it('allows direct API calls to paths listed in allowed_api_paths', () => {
Expand Down
8 changes: 4 additions & 4 deletions e2e-tests/cypress/e2e/Direct-kibana-request.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import * as semver from 'semver';
import { getKibanaVersion, userCredentials } from '../support/helpers';
import { kbnApiAdvancedClient } from '../support/helpers/KbnApiAdvancedClient';
import { kbnApiClient } from '../support/helpers/KbnApiClient';
import { rorApiClient } from '../support/helpers/RorApiClient';
import { Settings } from '../support/page-objects/Settings';

describe('Direct kibana request', () => {
const user1 = 'user1:dev';
const admin = 'admin:dev';

beforeEach(() => {
clearDirectKibanaRequestState();
rorApiClient.configureRorIndexMainSettings('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
});

afterEach(() => {
clearDirectKibanaRequestState();
rorApiClient.configureRorIndexMainSettings('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
});

it('should check direct kibana request', () => {
Expand Down Expand Up @@ -84,7 +84,7 @@ describe('Direct kibana request', () => {
});

it('should create short URL with x-ror-tenancy-id header', () => {
rorApiClient.configureRorIndexMainSettings('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');

const createShortUrl = semver.gte(getKibanaVersion(), '8.0.0')
? kbnApiClient.createShortUrl(
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/cypress/e2e/Discover.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getKibanaVersion } from '../support/helpers';
import { esApiAdvancedClient } from '../support/helpers/EsApiAdvancedClient';
import { SearchSessions } from '../support/page-objects/SearchSessions';

const userCredentials = 'user4:dev';
const userCredentials = 'user2:dev';
const tenantIndex = '.kibana_admins_group';
const indexWithSearchSessions = semver.lt(getKibanaVersion(), '8.0.0')
? `${tenantIndex}_${getKibanaVersion()}_001`
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/cypress/e2e/Forbidden-login.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Settings } from '../support/page-objects/Settings';

describe('Forbidden login test', () => {
before(() => {
Settings.setSettingsData('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
});

beforeEach(() => {
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/cypress/e2e/Hide_apps.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Home } from '../support/page-objects/Home';

describe('hidden apps', () => {
afterEach(() => {
Settings.setSettingsData('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
});

context('Stack Management navigation', () => {
Expand Down
198 changes: 198 additions & 0 deletions e2e-tests/cypress/e2e/Readonlyrest-settings.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { esApiAdvancedClient } from '../support/helpers/EsApiAdvancedClient';
import { esApiClient } from '../support/helpers/EsApiClient';
import { kbnApiAdvancedClient } from '../support/helpers/KbnApiAdvancedClient';
import { Dashboard } from '../support/page-objects/Dashboard';
import { Discover } from '../support/page-objects/Discover';
import { Login } from '../support/page-objects/Login';
import { RorMenu } from '../support/page-objects/RorMenu';
import { Settings } from '../support/page-objects/Settings';
import { Tenancy } from '../support/page-objects/Tenancy';

describe('Readonlyrest-settings', () => {
const customSessionIndex = `test_index`;
const adminCredentials = 'admin:dev';

afterEach(() => {
Settings.setReadonlyRestKbnSettings();
esApiClient.deleteIndex(customSessionIndex);
kbnApiAdvancedClient.deleteSavedObjects(adminCredentials);
kbnApiAdvancedClient.deleteSavedObjects(adminCredentials, 'template_group');
});

it('should disable multitenancy', () => {
Settings.setReadonlyRestKbnSettings(`
multiTenancyEnabled: false
`);
Login.initialization({ finishUrl: '/app/home' });
RorMenu.openRorMenu();
RorMenu.verifyNoTenantAvailable();
});

// The docker env (elk-ror) runs 2 kbn-ror replicas behind kbn-proxy's round robin (see
// base.docker-compose.yml). resetKibanaIndexToTemplate is only applied once, at tenant-index
// creation time (TenantIndexBasedOnTemplateApplier, called from abstractIndexCreator.ts) - unlike
// the CSS/JS/middleware injections elsewhere in this spec, which re-evaluate on every request and
// so self-correct if an early request lands on a stale replica. If the one request that creates
// .kibana_admins_group lands on a replica that has not yet picked up the settings POSTed above,
// the reset never happens and nothing later can retrigger it. The eck-* environments run a single
// Kibana node (kind-cluster/ror/base/kbn.yml: count: 1) and are unaffected.
(Cypress.env().envName === 'elk-ror' ? it.skip : it)('should verify kibanaIndexTemplate functionality', () => {
Settings.setReadonlyRestKbnSettings(`
kibanaIndexTemplate: ".kibana_template_group"
resetKibanaIndexToTemplate: true
`);

cy.kbnImport({
endpoint: 'api/saved_objects/_import?overwrite=true',
credentials: adminCredentials,
fixtureFilename: 'audit_dashboard.ndjson',
currentGroupHeader: 'template_group'
});

Login.initialization();
Discover.openDataViewPage();
Discover.verifyIndexPatternSwitchLink('AUDIT_INDEX_PATTERN');
Dashboard.openDashboard();
Dashboard.verifyDashboardExists('ReadonlyREST Audit Dashboard');

// Verify that the index is reset to the template
cy.kbnImport({
endpoint: 'api/saved_objects/_import?overwrite=true',
credentials: adminCredentials,
fixtureFilename: 'file.ndjson',
currentGroupHeader: 'admins_group'
});

cy.reload();
Dashboard.openDashboard();
Dashboard.verifyDashboardNotExist('Look at my dashboard');
});

it('should verify index based session', () => {
Settings.setReadonlyRestKbnSettings(`
store_sessions_in_index: true
sessions_index_name: ${customSessionIndex}
`);

Login.initialization();
esApiAdvancedClient.waitForDocsCount(customSessionIndex, 1);
});

it('should verify custom Kibana CSS', () => {
Login.initialization();

Settings.setReadonlyRestKbnSettings(`
kibana_custom_css_inject: 'h1 { color: rgb(0,128,0) !important;}'
`);

cy.reload();

cy.get('h1').shouldHaveStyle('color', 'rgb(0,128,0)');
});

it('should verify custom Kibana JS', () => {
Login.initialization();

Settings.setReadonlyRestKbnSettings(`
kibana_custom_js_inject: "if (window.ROR_METADATA.customMetadata && window.ROR_METADATA.customMetadata.alert_message) {
const div = document.createElement('div');
div.setAttribute('data-testid', 'metadata-alert-message');
div.textContent = window.ROR_METADATA.customMetadata.alert_message;
document.body.appendChild(div);
};"
`);

cy.reload();

cy.get('[data-testid="metadata-alert-message"]')
.should('exist')
.then($el => {
cy.log(`Alert message: ${$el.text()}`);

cy.wrap($el).should('contain', 'Dear admin');
});
});

it('should verify custom middleware', () => {
Login.initialization();

Settings.setReadonlyRestKbnSettings(`
kibana_custom_js_inject: "if (window.ROR_METADATA.enrichedData) {
const div = document.createElement('div');
div.setAttribute('data-testid', 'metadata-enriched-data');
div.textContent = window.ROR_METADATA.enrichedData;
document.body.appendChild(div);
};"
custom_middleware_inject: "async function customMiddleware(req, res, next) {
const metadata =
req.rorRequest && req.rorRequest.getIdentitySession() && req.rorRequest.getIdentitySession().metadata;

if (metadata && metadata.username === 'admin') {
req.rorRequest.enrichIdentitySessionMetadata({
enrichedData: 'custom enriched data',
});
}

return next();
}"
`);

cy.reload();

cy.get('[data-testid="metadata-enriched-data"]')
.should('exist')
.then($el => {
cy.log(`Entiched data: ${$el.text()}`);

cy.wrap($el).should('contain', 'custom enriched data');
});
});

it('should verify whitelisted Urls', () => {
Settings.setReadonlyRestKbnSettings(`
whitelistedPaths: [".*/api/status$", ".*/api/index_management/indices$"]
`);

cy.request(`${Cypress.config().baseUrl}/api/index_management/indices`).then(response => {
expect(response.status).to.equal(200);
});

cy.request({ url: `${Cypress.config().baseUrl}/api/spaces/space`, failOnStatusCode: false }).then(response => {
expect(response.status).to.equal(403);
expect(response.body.error).to.equal('Unauthorized');
});
});

it('should open correct tenancy after login when custom middleware sets defaultGroup', () => {
Settings.setReadonlyRestKbnSettings(`
custom_middleware_inject: "async function customMiddleware(req, res, next) {
const rorRequest = req.rorRequest;
const userRequest = rorRequest && (await req.rorRequest.getUserRequestIdentity());
const metadata = userRequest && userRequest.metadata;
const defaultGroup = 'infosec_group';

if (rorRequest.getPath() === '/login' && rorRequest.getMethod() === 'post') {
if (rorRequest.getBody().username === 'admin') {
rorRequest.setQuery('defaultGroup', defaultGroup);
}
}

if (metadata && rorRequest.getPath() === '/pkp/api/info') {
const availableGroups = metadata.availableGroups;
if (availableGroups.some(availableGroup => availableGroup.id === defaultGroup)) {
const reorderedGroups = [...availableGroups].sort((a, b) =>
a.id === defaultGroup ? -1 : b.id === defaultGroup ? 1 : 0
);
rorRequest.enrichIdentitySessionMetadata({ availableGroups: reorderedGroups });
}
}

return next();
}"
`);

Login.initialization();

Tenancy.checkTenancyNameInBadge('infosec', 'a');
});
});
2 changes: 1 addition & 1 deletion e2e-tests/cypress/e2e/Reporting-index.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('Reporting index', () => {
if (semver.gte(getKibanaVersion(), '8.0.0')) {
kbnApiAdvancedClient.deleteDataViews(admin, 'infosec_group');
}
Settings.setSettingsData('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
});

it('should correctly match index pattern when audit index_template contains .reporting', () => {
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/cypress/e2e/Sanity-check-ro-kibana-access.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { userCredentials } from '../support/helpers';

describe('sanity check ro kibana access', () => {
afterEach(() => {
Settings.setSettingsData('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
kbnApiClient.deleteSampleData('ecommerce', userCredentials, 'template_group');
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { userCredentials } from '../support/helpers';

describe('sanity check ro_strict kibana access', () => {
afterEach(() => {
Settings.setSettingsData('defaultSettings.yaml');
Settings.setSettingsData('defaultReadonlyRestEsAndKbnSettings.yaml');
kbnApiClient.deleteSampleData('ecommerce', userCredentials, 'template_group');
});

Expand Down
5 changes: 3 additions & 2 deletions e2e-tests/cypress/e2e/Settings.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('settings', () => {
cy.log('should check save changes functionality when success');
Editor.replaceValues('PERSONAL_GRP', `PERSONAL_GRP${Cypress._.random(0, 1e6)}`);
Settings.clickSaveButton();
Settings.confirmSaveModal();
// Settings.successfulSavedConfigurationToast().should('be.visible');
});

Expand All @@ -42,9 +43,9 @@ describe('settings', () => {

Login.initialization({ credentials: { username, password } });
Settings.open();
cy.intercept('POST', '/pkp/api/settings').as('saveSettings');
cy.intercept({ method: 'POST', pathname: '/pkp/api/settings' }).as('saveSettings');
Settings.clickSaveButton();

Settings.confirmSaveModal();
cy.wait('@saveSettings').its('response.statusCode').should('equal', 200);
});
});
1 change: 1 addition & 0 deletions e2e-tests/cypress/e2e/Test-settings.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ describe('Test ACL', () => {
Settings.open();
Settings.reloadFromFileSettings();
Settings.clickSaveButton();
Settings.confirmSaveModal();
TestSettings.setDefaultData();
});

Expand Down
36 changes: 0 additions & 36 deletions e2e-tests/cypress/e2e/ror-config.cy.ts

This file was deleted.

Loading
Loading