Skip to content

Commit

Permalink
Merge pull request #475 from PagerDuty/release/0.13.1-beta.0
Browse files Browse the repository at this point in the history
  • Loading branch information
gsreynolds authored Jul 29, 2024
2 parents 7a2793d + 8d3726f commit e94b80b
Show file tree
Hide file tree
Showing 54 changed files with 1,732 additions and 1,834 deletions.
5 changes: 2 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,16 @@ module.exports = {
'react-refresh',
],
rules: {
'max-len': [WARN, { code: 120, ignorePattern: '^import\\W.*', ignoreTrailingComments: true }],
'max-len': [WARN, { code: 180, ignorePattern: '^import\\W.*', ignoreTrailingComments: true }],
'object-curly-newline': [
WARN,
{ ObjectPattern: { multiline: true, minProperties: 1 }, ImportDeclaration: 'always' },
],
'react/prop-types': OFF, // To be done in another refactor
// 'react/jsx-filename-extension': [ERROR, { extensions: ['.js', '.jsx'] }],
'react/jsx-filename-extension': [ERROR, { extensions: ['.js', '.jsx'] }],
'no-param-reassign': [ERROR, { props: true, ignorePropertyModificationsFor: ['draft'] }],
'no-use-before-define': [ERROR, { functions: false }],
'no-plusplus': [ERROR, { allowForLoopAfterthoughts: true }],
'react-refresh/only-export-components': OFF, // To be done in another refactor
'react-hooks/exhaustive-deps': OFF, // To be done in another refactor
'react-hooks/rules-of-hooks': OFF, // To be done in another refactor
},
Expand Down
127 changes: 108 additions & 19 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,28 +141,117 @@ 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) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
});
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) => {
// eslint-disable-next-line no-unused-expressions
expect($el.text()).to.exist;
});
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
7 changes: 2 additions & 5 deletions cypress/e2e/app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,9 @@ describe('PagerDuty Live', { failFast: { enabled: true } }, () => {
});

it('Application correctly renders the catastrophe modal', () => {
cy
.window()
.its('store')
.invoke('dispatch', { type: 'CATASTROPHE' });
cy.window().its('store').invoke('dispatch', { type: 'CATASTROPHE' });

cy.get('header').contains('Catastrophic Error');
cy.get('header').contains('Unexpected Error');
cy.get('p').contains('The application will restart');
});
});
25 changes: 19 additions & 6 deletions cypress/support/util/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,22 +255,35 @@ 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(':'),
);
cy.get(`#column-${columnId}-add-icon`).click();
});
cy.get('#save-columns-button').click();
checkActionAlertsModalContent('Incident table columns saved');
Expand Down
38 changes: 19 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "pd-live-react",
"homepage": "https://pagerduty.github.io/pd-live-react",
"version": "0.13.0-beta.0",
"version": "0.13.1-beta.0",
"private": true,
"dependencies": {
"@chakra-ui/icons": "^2.1.1",
"@chakra-ui/react": "^2.8.0",
"@datadog/browser-rum": "^5.14.0",
"@datadog/datadog-ci": "^2.37.0",
"@datadog/datadog-ci": "^2.40.1",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@emotion/styled": "^11.13.0",
"@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-regular-svg-icons": "^6.5.1",
Expand All @@ -27,11 +27,11 @@
"date-fns": "^2.29.3",
"font-awesome": "^4.7.0",
"framer-motion": "^10.16.2",
"fuse.js": "^6.6.2",
"fuse.js": "^7.0.0",
"i18next": "^23.7.6",
"i18next-browser-languagedetector": "^7.1.0",
"i18next-browser-languagedetector": "^8.0.0",
"immer": "^10.0.2",
"jsonpath-plus": "^7.2.0",
"jsonpath-plus": "^9.0.0",
"linkify-react": "^4.1.3",
"linkifyjs": "^4.1.3",
"lodash": "^4.17.21",
Expand All @@ -49,15 +49,15 @@
"react-icons": "^5.2.1",
"react-minimal-pie-chart": "^8.4.0",
"react-redux": "^9.1.2",
"react-select": "^5.7.7",
"react-select": "^5.8.0",
"react-table": "^7.8.0",
"react-window": "^1.8.8",
"react-window": "^1.8.10",
"redux": "^4.2.1",
"redux-persist": "^6.0.0",
"redux-saga": "^1.2.1",
"styled-components": "^6.0.4",
"use-debounce": "^9.0.3",
"validator": "^13.11.0",
"validator": "^13.12.0",
"web-vitals": "^3.5.2"
},
"scripts": {
Expand Down Expand Up @@ -106,47 +106,47 @@
"@faker-js/faker": "^8.0.2",
"@testing-library/dom": "^9.3.4",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.1.2",
"@testing-library/react": "^15.0.7",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.3",
"@vitejs/plugin-react": "^4.2.1",
"@welldone-software/why-did-you-render": "^7.0.1",
"@welldone-software/why-did-you-render": "^8.0.3",
"babel-jest": "^29.6.3",
"cypress": "^13.5.1",
"cypress": "^13.13.1",
"cypress-fail-fast": "^7.1.0",
"cypress-real-events": "^1.11.0",
"dotenv": "^16.4.4",
"dotenv": "^16.4.5",
"eslint": "^8.43.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^9.0.0",
"eslint-config-react-app": "^7.0.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-cypress": "^2.15.1",
"eslint-plugin-cypress": "^3.4.0",
"eslint-plugin-import": "^2.29.0",
"eslint-plugin-jsx": "^0.1.0",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.3",
"eslint-plugin-styled-components-a11y": "^2.1.31",
"eslint-plugin-styled-components-a11y": "^2.1.35",
"genversion": "^3.1.1",
"gh-pages": "^6.1.1",
"i18next-parser": "^8.12.0",
"i18next-parser": "^9.0.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.5.2",
"jest-environment-jsdom": "^29.7.0",
"jest-environment-node": "^29.7.0",
"jest-location-mock": "^1.0.10",
"jest-location-mock": "^2.0.0",
"jest-transformer-svg": "^2.0.1",
"prettier": "^3.1.0",
"prettier-eslint": "^16.1.2",
"prettier-eslint-cli": "^8.0.1",
"redux-mock-store": "^1.5.4",
"redux-saga-test-plan": "^4.0.6",
"sass": "^1.77.5",
"string.prototype.replaceall": "^1.0.6",
"string.prototype.replaceall": "^1.0.10",
"vite": "^4.5.3",
"vite-plugin-environment": "^1.1.3",
"vite-plugin-eslint": "^1.8.1",
Expand Down
35 changes: 13 additions & 22 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ import {
} from 'src/redux/monitoring/actions';

import {
PD_USER_TOKEN,
PD_OAUTH_CLIENT_ID,
PD_OAUTH_CLIENT_SECRET,
PD_USER_TOKEN, PD_OAUTH_CLIENT_ID, PD_OAUTH_CLIENT_SECRET,
} from 'src/config/constants';

import 'src/App.scss';
Expand Down Expand Up @@ -108,9 +106,10 @@ const App = () => {
);

const {
status: connectionStatus,
connectionStatusMessage,
} = useSelector((state) => state.connection);
status: connectionStatus, connectionStatusMessage,
} = useSelector(
(state) => state.connection,
);
const [catastrophe, setCatastrophe] = useState(false);
useEffect(() => {
if (connectionStatus === CATASTROPHE) {
Expand Down Expand Up @@ -163,17 +162,10 @@ const App = () => {
}, []);

if (catastrophe) {
return (
<CatastropheModal
errorMessage={connectionStatusMessage}
/>
);
return <CatastropheModal errorMessage={connectionStatusMessage} />;
}

if (
!PD_USER_TOKEN
&& (typeof token !== 'string' || !token.startsWith('pd'))
) {
if (!PD_USER_TOKEN && (typeof token !== 'string' || !token.startsWith('pd'))) {
return (
<div className="App">
<AuthComponent clientId={PD_OAUTH_CLIENT_ID} clientSecret={PD_OAUTH_CLIENT_SECRET} />
Expand Down Expand Up @@ -201,13 +193,12 @@ const App = () => {

return (
<div className="App">
<ErrorBoundary fallbackRender={
(details) => {
RealUserMonitoring.trackError(details.error);
dispatchCatastrophe(`UI Render error: ${details.error.message}`);
return null;
}
}
<ErrorBoundary
fallbackRender={(details) => {
RealUserMonitoring.trackError(details.error);
dispatchCatastrophe(`UI Render error: ${details.error.message}`);
return null;
}}
>
<Box position="fixed" w="100%" h="100%" overflow="hidden">
<Box as="header" top={0} w="100%" pb={1}>
Expand Down
Loading

0 comments on commit e94b80b

Please sign in to comment.