Skip to content
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

Add support for computed columns #463

Merged
merged 26 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a40f363
local checkpoint 1
martindstone Jun 12, 2024
c176204
Add additional test for existing column generator functionality
gsreynolds Jun 30, 2024
6eb1d6f
Add regex-single and regex test for hostname in incident details
gsreynolds Jun 30, 2024
70c6b4e
Add computed null condition tests
gsreynolds Jun 30, 2024
37a1dbb
Remove console.log statements from column-generator
gsreynolds Jun 30, 2024
708da0a
computed columns UI WIP
gsreynolds Jun 30, 2024
251b7b9
computed columns UI WIP 2
gsreynolds Jul 2, 2024
88a61e5
computed columns UI WIP 3
gsreynolds Jul 5, 2024
756fb18
Reduce duplication of values/ids/labels etc so they are defined in fe…
gsreynolds Jul 11, 2024
3d898a9
Clear Local Cache should *really* clear local storage and session sto…
gsreynolds Jul 12, 2024
adeef0d
Ensure value is loaded from saved columns and that expression/express…
gsreynolds Jul 12, 2024
bbc557c
Remove redundant aggregator from alert columns, always null
gsreynolds Jul 12, 2024
d90a3d2
Add validation to add column functions and set default state of colum…
gsreynolds Jul 12, 2024
8a71dfa
react-table requires id, but derive it now from value and not accesso…
gsreynolds Jul 12, 2024
87e3b65
Column IDs are now the full value and not just the accessor
gsreynolds Jul 12, 2024
0c355ed
Add e2e test for adding computed columns
gsreynolds Jul 12, 2024
52eb921
Add e2e test for multiple computed columns with the same accessor
gsreynolds Jul 12, 2024
49bc0ad
Update locales
gsreynolds Jul 12, 2024
321b8c5
Remove duplicated function
gsreynolds Jul 16, 2024
0459b8d
Ensure expression and expressionType are persisted as needed to set t…
gsreynolds Jul 17, 2024
38ac483
Pass custom column as argument and construct value later. Improve e2e…
gsreynolds Jul 18, 2024
3f71eab
Guard against computed or alert column state being undefined
gsreynolds Jul 18, 2024
d10b56b
Remove console.errors
gsreynolds Jul 19, 2024
da8d78e
clean up some formatting
martindstone Jul 19, 2024
e703506
oops, take out garish colors
martindstone Jul 19, 2024
073e65e
Update unit tests for custom column UI changes
gsreynolds Jul 23, 2024
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
84 changes: 71 additions & 13 deletions cypress/e2e/Settings/settings.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
updateDarkMode,
updateRelativeDates,
manageIncidentTableColumns,
manageCustomAlertColumnDefinitions,
manageCustomColumnDefinitions,
checkIncidentCellContentAllRows,
checkActionAlertsModalContent,
} from '../../support/util/common';
Expand Down Expand Up @@ -141,27 +141,85 @@ describe('Manage Settings', { failFast: { enabled: true } }, () => {
});

it('Add valid custom alert column to incident table', () => {
const customAlertColumnDefinitions = ['Quote:details.quote'];
manageCustomAlertColumnDefinitions(customAlertColumnDefinitions);
customAlertColumnDefinitions.forEach((columnName) => {
const header = columnName.split(':')[0];
cy.get(`[data-column-name="${header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
const customColumnDefinitions = [
{ header: 'Quote', accessorPath: 'details.quote', expression: '' },
];
manageCustomColumnDefinitions(customColumnDefinitions);
customColumnDefinitions.forEach((column) => {
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
// Quote exists in the alert body, so it should not be empty
expect($el.text()).to.not.equal('--');
expect($el.text().length).to.be.greaterThan(20);
});
});
});

it('Add valid custom alert column with JSON path containing spaces to incident table', () => {
const customAlertColumnDefinitions = ["Fav Flavour:details.['favorite ice cream flavor']"];
manageCustomAlertColumnDefinitions(customAlertColumnDefinitions);
customAlertColumnDefinitions.forEach((columnName) => {
const header = columnName.split(':')[0];
cy.get(`[data-column-name="${header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
const customColumnDefinitions = [
{ header: 'Fav Flavour', accessorPath: "details.['favorite ice cream flavor']", expression: '' },
];
manageCustomColumnDefinitions(customColumnDefinitions);
customColumnDefinitions.forEach((column) => {
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
// Fav Flavour doesn't exist in the alert body, so it should be empty
expect($el.text()).to.equal('--');
});
});
});

it('Add valid custom computed column to incident table', () => {
const customColumnDefinitions = [
{ header: 'CI', accessorPath: 'first_trigger_log_entry.channel.details', expression: '(.*.example.com)' },
];
manageCustomColumnDefinitions(customColumnDefinitions, 'computed');
customColumnDefinitions.forEach((column) => {
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
// CI doesn't exist in the alert body, so it should be empty
expect($el.text()).to.equal('--');
});
});
});

it('Add two valid custom computed column to incident table with different expressions', () => {
const customColumnDefinitions = [
{ header: 'CI', accessorPath: 'first_trigger_log_entry.channel.details', expression: '(.*.example.com)' },
{ header: 'Category', accessorPath: 'first_trigger_log_entry.channel.details', expression: 'Category(.*)' },
];
manageCustomColumnDefinitions(customColumnDefinitions, 'computed');
customColumnDefinitions.forEach((column) => {
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
// CI or Category don't exist in the alert body, so it should be empty
expect($el.text()).to.equal('--');
});
});
});

it('Add valid quote custom computed column to incident table', () => {
const customColumnDefinitions = [
{ header: 'QuoteRegex', accessorPath: 'first_trigger_log_entry.channel.details', expression: '{"quote":"(.*)"}' },
];
manageCustomColumnDefinitions(customColumnDefinitions, 'computed');
customColumnDefinitions.forEach((column) => {
cy.get(`[data-column-name="${column.header}"]`).scrollIntoView().should('be.visible');
cy.get(`[data-incident-header="${column.header}"][data-incident-row-cell-idx="0"]`).then(($el) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
// Quote does exist in the alert body, so it should not be empty and also shouldn't contain the custom details JSON with quote key, just the quote value
expect($el.text()).to.not.equal('--');
expect($el.text()).to.not.contain('"quote"');
expect($el.text().length).to.be.greaterThan(20);
});
});
});
Expand Down
21 changes: 15 additions & 6 deletions cypress/support/util/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,22 +255,31 @@ export const manageIncidentTableColumns = (desiredState = 'add', columns = []) =
checkActionAlertsModalContent('Incident table columns saved');
};

export const manageCustomAlertColumnDefinitions = (customAlertColumnDefinitions) => {
export const manageCustomColumnDefinitions = (customColumnDefinitions, type = 'alert') => {
cy.get('.settings-panel-dropdown').click();
cy.get('.dropdown-item').contains('Columns').click();

cy.get('#custom-columns-card-body .chakra-icon').each(($el) => {
cy.wrap($el).click();
});

customAlertColumnDefinitions.forEach((customAlertColumnDefinition) => {
const [header, accessorPath] = customAlertColumnDefinition.split(':');
cy.get('input[placeholder="Header"]').type(header);
cy.get('input[placeholder="JSON Path"]').type(accessorPath);
customColumnDefinitions.forEach((customColumnDefinition) => {
const {
header, accessorPath, expression,
} = customColumnDefinition;
cy.get('#column-type-select').select(type);
cy.get('input[placeholder="Header"]').clear().type(header);
cy.get('input[placeholder="JSON Path"]').clear().type(accessorPath);
if (type === 'computed') {
cy.get('input[placeholder="Regex"]').clear().type(expression, { parseSpecialCharSequences: false });
}
cy.get('button[aria-label="Add custom column"]').click();
// Need to escape special characters in accessorPath
// https://docs.cypress.io/faq/questions/using-cypress-faq#How-do-I-use-special-characters-with-cyget
cy.get(`#column-${Cypress.$.escapeSelector(accessorPath)}-add-icon`).click();
const columnId = Cypress.$.escapeSelector(
[header, accessorPath, expression.replace(/:/g, '\\:')].filter((value) => value !== '').join(':'),
Dismissed Show dismissed Hide dismissed
);
cy.get(`#column-${columnId}-add-icon`).click();
});
cy.get('#save-columns-button').click();
checkActionAlertsModalContent('Incident table columns saved');
Expand Down
Loading
Loading