Skip to content

Commit

Permalink
[GEN-2177]: add awaitToast function for improved notification handlin…
Browse files Browse the repository at this point in the history
…g in Cypress tests (#2165)

This pull request includes several changes aimed at improving the
Cypress tests and adding new constants for better identification and
notifications. The most important changes include updates to the Cypress
test files to add toast notifications, modifications to constants for
better data identification, and adjustments to the test descriptions to
include source and destination counts.

### Updates to Cypress tests:

*
[`frontend/webapp/cypress/e2e/02-onboarding.cy.ts`](diffhunk://#diff-d5819393774dc93d8cee9a6f11c4f6c459bdfa2b031b263bbba79dad3a342dcdL6-R12):
Modified the test to check for the existence of 5 sources within the
"default" namespace.
*
[`frontend/webapp/cypress/e2e/03-sources.cy.ts`](diffhunk://#diff-981488421b684f7ca98e7e8b147b14c23fe2c57e876d88ca981c563c8ba003cdL1-R1):
Added `awaitToast` function calls to wait for toast notifications and
modified the test to check for the existence of sources within the
namespace.
[[1]](diffhunk://#diff-981488421b684f7ca98e7e8b147b14c23fe2c57e876d88ca981c563c8ba003cdL1-R1)
[[2]](diffhunk://#diff-981488421b684f7ca98e7e8b147b14c23fe2c57e876d88ca981c563c8ba003cdL23-R31)
[[3]](diffhunk://#diff-981488421b684f7ca98e7e8b147b14c23fe2c57e876d88ca981c563c8ba003cdR53-R57)
[[4]](diffhunk://#diff-981488421b684f7ca98e7e8b147b14c23fe2c57e876d88ca981c563c8ba003cdL75-R75)
*
[`frontend/webapp/cypress/e2e/04-destinations.cy.ts`](diffhunk://#diff-6f34bd7eb1cce2b4683938973757c4b0e80921234633a259cd17674c0805ca1bL1-R1):
Added `awaitToast` function calls to wait for toast notifications and
updated test descriptions to include notification checks.
[[1]](diffhunk://#diff-6f34bd7eb1cce2b4683938973757c4b0e80921234633a259cd17674c0805ca1bL1-R1)
[[2]](diffhunk://#diff-6f34bd7eb1cce2b4683938973757c4b0e80921234633a259cd17674c0805ca1bL14-R14)
[[3]](diffhunk://#diff-6f34bd7eb1cce2b4683938973757c4b0e80921234633a259cd17674c0805ca1bR26-R33)
[[4]](diffhunk://#diff-6f34bd7eb1cce2b4683938973757c4b0e80921234633a259cd17674c0805ca1bR48-R59)
[[5]](diffhunk://#diff-6f34bd7eb1cce2b4683938973757c4b0e80921234633a259cd17674c0805ca1bR72-R75)
*
[`frontend/webapp/cypress/e2e/05-actions.cy.ts`](diffhunk://#diff-adc830d3310d3ba00c598b867a2b4f782e4fc6d3147fdb7af3f6346eb6d2f79fL1-R1):
Added `awaitToast` function calls to wait for toast notifications and
updated test descriptions to include notification checks.
[[1]](diffhunk://#diff-adc830d3310d3ba00c598b867a2b4f782e4fc6d3147fdb7af3f6346eb6d2f79fL1-R1)
[[2]](diffhunk://#diff-adc830d3310d3ba00c598b867a2b4f782e4fc6d3147fdb7af3f6346eb6d2f79fL26-R29)
[[3]](diffhunk://#diff-adc830d3310d3ba00c598b867a2b4f782e4fc6d3147fdb7af3f6346eb6d2f79fR49-R53)
[[4]](diffhunk://#diff-adc830d3310d3ba00c598b867a2b4f782e4fc6d3147fdb7af3f6346eb6d2f79fL57-R63)
[[5]](diffhunk://#diff-adc830d3310d3ba00c598b867a2b4f782e4fc6d3147fdb7af3f6346eb6d2f79fR72-R75)
*
[`frontend/webapp/cypress/e2e/06-rules.cy.ts`](diffhunk://#diff-aba373cc082245b95ade17d84a085f3f05f6feccbc7d9ee511cb3cc6b4927dd6L1-R1):
Added `awaitToast` function calls to wait for toast notifications and
updated test descriptions to include notification checks.
[[1]](diffhunk://#diff-aba373cc082245b95ade17d84a085f3f05f6feccbc7d9ee511cb3cc6b4927dd6L1-R1)
[[2]](diffhunk://#diff-aba373cc082245b95ade17d84a085f3f05f6feccbc7d9ee511cb3cc6b4927dd6L24-R27)
[[3]](diffhunk://#diff-aba373cc082245b95ade17d84a085f3f05f6feccbc7d9ee511cb3cc6b4927dd6R47-R51)
[[4]](diffhunk://#diff-aba373cc082245b95ade17d84a085f3f05f6feccbc7d9ee511cb3cc6b4927dd6L55-R61)
[[5]](diffhunk://#diff-aba373cc082245b95ade17d84a085f3f05f6feccbc7d9ee511cb3cc6b4927dd6R70-R73)

### Modifications to constants:

*
[`frontend/webapp/cypress/constants/index.ts`](diffhunk://#diff-ffe3e5bc9ff7bba75f2007551dd3e69fa93e9638a7fb62ceec23414f8333f491R29):
Added new constants for namespace sources, data IDs for sources, and
toast notifications.
[[1]](diffhunk://#diff-ffe3e5bc9ff7bba75f2007551dd3e69fa93e9638a7fb62ceec23414f8333f491R29)
[[2]](diffhunk://#diff-ffe3e5bc9ff7bba75f2007551dd3e69fa93e9638a7fb62ceec23414f8333f491R41)
[[3]](diffhunk://#diff-ffe3e5bc9ff7bba75f2007551dd3e69fa93e9638a7fb62ceec23414f8333f491R65-R68)
[[4]](diffhunk://#diff-ffe3e5bc9ff7bba75f2007551dd3e69fa93e9638a7fb62ceec23414f8333f491L105-R126)

### Minor code adjustments:

*
[`frontend/webapp/app/layout.tsx`](diffhunk://#diff-788a38ec94bfca9467b13cb6eb93cdeccd4237facfb5fff310e05b3af67413efL9):
Removed the `position: 'fixed'` style from `LAYOUT_STYLE`.
*
[`frontend/webapp/containers/main/sources/choose-sources/choose-sources-body/choose-sources-body-fast/sources-list/index.tsx`](diffhunk://#diff-6b67649d370d208941f4e5a78c0c9de2f5b9b65fd49e0ede8ef57066982450aaL116-R116):
Added `data-id` attributes to `Group` and `SourceItem` components for
better identification.
[[1]](diffhunk://#diff-6b67649d370d208941f4e5a78c0c9de2f5b9b65fd49e0ede8ef57066982450aaL116-R116)
[[2]](diffhunk://#diff-6b67649d370d208941f4e5a78c0c9de2f5b9b65fd49e0ede8ef57066982450aaL144-R144)
  • Loading branch information
BenElferink authored Jan 9, 2025
1 parent c5409cd commit 419f5ea
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 46 deletions.
1 change: 0 additions & 1 deletion frontend/webapp/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { ApolloWrapper } from '@/lib';
import { ThemeProviderWrapper } from '@/styles';

const LAYOUT_STYLE: React.CSSProperties = {
position: 'fixed',
width: '100vw',
height: '100vh',
margin: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const SourcesList: React.FC<Props> = ({
const hasFilteredSources = !!filteredSources.length;

return (
<Group data-id={`namespace-${namespace}`} key={`namespace-${namespace}`} $selected={isNamespaceAllSourcesSelected} $isOpen={isNamespaceSelected && hasFilteredSources}>
<Group key={`namespace-${namespace}`} data-id={`namespace-${namespace}`} $selected={isNamespaceAllSourcesSelected} $isOpen={isNamespaceSelected && hasFilteredSources}>
<NamespaceItem $selected={isNamespaceAllSourcesSelected} onClick={() => onSelectNamespace(namespace)}>
<FlexRow>
<Checkbox value={isNamespaceAllSourcesSelected} onChange={(bool) => onSelectAll(bool, namespace)} />
Expand Down Expand Up @@ -141,7 +141,7 @@ export const SourcesList: React.FC<Props> = ({
const isSourceSelected = !!onlySelectedSources.find(({ name }) => name === source.name);

return (
<SourceItem key={`source-${source.name}`} $selected={isSourceSelected} onClick={() => onSelectSource(source)}>
<SourceItem key={`source-${source.name}`} data-id={`source-${source.name}`} $selected={isSourceSelected} onClick={() => onSelectSource(source)}>
<FlexRow>
<Checkbox value={isSourceSelected} onChange={() => onSelectSource(source, namespace)} />
<Text>{source.name}</Text>
Expand Down
24 changes: 22 additions & 2 deletions frontend/webapp/cypress/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const NAMESPACES = {

export const SELECTED_ENTITIES = {
NAMESPACE: NAMESPACES.DEFAULT,
NAMESPACE_SOURCES: ['coupon', 'frontend', 'inventory', 'membership', 'pricing'],
SOURCE: 'frontend',
DESTINATION_TYPE: 'jaeger',
DESTINATION_DISPLAY_NAME: 'Jaeger',
Expand All @@ -37,6 +38,7 @@ export const SELECTED_ENTITIES = {

export const DATA_IDS = {
SELECT_NAMESPACE: `[data-id=namespace-${SELECTED_ENTITIES.NAMESPACE}]`,
SELECT_SOURCE: (sourceName: string) => `[data-id=source-${sourceName}]`,
SELECT_DESTINATION: `[data-id=select-potential-destination-${SELECTED_ENTITIES.DESTINATION_TYPE}]`,
SELECT_DESTINATION_AUTOFILL_FIELD: `[data-id=${SELECTED_ENTITIES.DESTINATION_AUTOFILL_FIELD}]`,

Expand All @@ -60,6 +62,10 @@ export const DATA_IDS = {
APPROVE: '[data-id=approve]',
DENY: '[data-id=deny]',

TOAST: '[data-id=toast]',
TOAST_CLOSE: '[data-id=toast-close]',
TOAST_ACTION: '[data-id=toast-action]',

SOURCE_NODE_HEADER: '[data-id=source-header]',
SOURCE_NODE: '[data-id=source-1]',
DESTINATION_NODE: '[data-id=destination-0]',
Expand Down Expand Up @@ -102,6 +108,20 @@ export const TEXTS = {
ACTION_WARN_MODAL_TITLE: `Delete action (${CYPRESS_TEST})`,
INSTRUMENTATION_RULE_WARN_MODAL_TITLE: `Delete rule (${CYPRESS_TEST})`,

NOTIF_SOURCES_CREATED: 'Successfully created 5 sources',
NOTIF_SOURCES_DELETED: 'Successfully deleted 5 sources',
NOTIF_SOURCES_CREATED: (amount: number) => `Successfully created ${amount} sources`,
NOTIF_SOURCES_UPDATED: (amount: number) => `Successfully updated ${amount} source`,
NOTIF_SOURCES_DELETED: (amount: number) => `Successfully deleted ${amount} sources`,

NOTIF_DESTINATIONS_CREATED: (amount: number) => `Successfully created ${amount} destinations`,
// TODO: this message isn't right, fix in backend
NOTIF_DESTINATIONS_UPDATED: (amount: number) => `Successfully transformed ${amount + 1} destinations to otelcol configuration`,
NOTIF_DESTINATIONS_DELETED: (amount: number) => `Successfully deleted ${amount} destinations`,

NOTIF_ACTION_CREATED: (crdId: string) => `Action "${crdId}" created`,
NOTIF_ACTION_UPDATED: (crdId: string) => `Action "${crdId}" updated`,
NOTIF_ACTION_DELETED: (crdId: string) => `Action "${crdId}" delete`,

NOTIF_INSTRUMENTATION_RULE_CREATED: (crdId: string) => `Rule "${crdId}" created`,
NOTIF_INSTRUMENTATION_RULE_UPDATED: (crdId: string) => `Rule "${crdId}" updated`,
NOTIF_INSTRUMENTATION_RULE_DELETED: (crdId: string) => `Rule "${crdId}" delete`,
};
7 changes: 5 additions & 2 deletions frontend/webapp/cypress/e2e/02-onboarding.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { BUTTONS, DATA_IDS, ROUTES, SELECTED_ENTITIES } from '../constants';
describe('Onboarding', () => {
beforeEach(() => cy.intercept('/graphql').as('gql'));

it('Should contain a "default" namespace', () => {
it('Should contain a "default" namespace, and it should have 5 sources', () => {
cy.visit(ROUTES.CHOOSE_SOURCES);
cy.wait('@gql').then(() => {
cy.get(DATA_IDS.SELECT_NAMESPACE).contains(SELECTED_ENTITIES.NAMESPACE).should('exist');
cy.get(DATA_IDS.SELECT_NAMESPACE).contains(SELECTED_ENTITIES.NAMESPACE).should('exist').click();
SELECTED_ENTITIES.NAMESPACE_SOURCES.forEach((sourceName) => {
cy.get(DATA_IDS.SELECT_NAMESPACE).get(DATA_IDS.SELECT_SOURCE(sourceName)).contains(sourceName).should('exist');
});
});
});

Expand Down
33 changes: 14 additions & 19 deletions frontend/webapp/cypress/e2e/03-sources.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getCrdById, getCrdIds, updateEntity } from '../functions';
import { awaitToast, getCrdById, getCrdIds, updateEntity } from '../functions';
import { BUTTONS, CRD_IDS, CRD_NAMES, DATA_IDS, NAMESPACES, ROUTES, SELECTED_ENTITIES, TEXTS } from '../constants';

// The number of CRDs that exist in the cluster before running any tests should be 0.
Expand All @@ -20,18 +20,15 @@ describe('Sources CRUD', () => {
cy.get(DATA_IDS.MODAL_ADD_SOURCE).should('exist');
cy.get(DATA_IDS.SELECT_NAMESPACE).find(DATA_IDS.CHECKBOX).click();

// Wait for 3 seconds to allow the namespace & it's resources to be loaded into the UI
cy.wait(3000).then(() => {
cy.contains('button', BUTTONS.DONE).click();
SELECTED_ENTITIES.NAMESPACE_SOURCES.forEach((sourceName) => {
cy.get(DATA_IDS.SELECT_NAMESPACE).get(DATA_IDS.SELECT_SOURCE(sourceName)).contains(sourceName).should('exist');
});

cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 5 }, () => {
// Wait for 5 seconds to allow the backend to batch an SSE notification
cy.wait(5000).then(() => {
cy.get(DATA_IDS.NOTIF_MANAGER_BUTTON).click();
cy.get(DATA_IDS.NOTIF_MANAGER_CONTENR).contains(TEXTS.NOTIF_SOURCES_CREATED).should('exist');
});
});
cy.contains('button', BUTTONS.DONE).click();

cy.wait('@gql').then(() => {
awaitToast({ withSSE: true, message: TEXTS.NOTIF_SOURCES_CREATED(5) }, () => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 5 });
});
});
});
Expand All @@ -53,7 +50,9 @@ describe('Sources CRUD', () => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 5 }, (crdIds) => {
const crdId = CRD_IDS.SOURCE;
expect(crdIds).includes(crdId);
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'serviceName', expectedValue: TEXTS.UPDATED_NAME });
awaitToast({ withSSE: false, message: TEXTS.NOTIF_SOURCES_UPDATED(1) }, () => {
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'serviceName', expectedValue: TEXTS.UPDATED_NAME });
});
});
});
},
Expand All @@ -72,12 +71,8 @@ describe('Sources CRUD', () => {
cy.get(DATA_IDS.APPROVE).click();

cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 }, () => {
// Wait for 5 seconds to allow the backend to batch an SSE notification
cy.wait(5000).then(() => {
cy.get(DATA_IDS.NOTIF_MANAGER_BUTTON).click();
cy.get(DATA_IDS.NOTIF_MANAGER_CONTENR).contains(TEXTS.NOTIF_SOURCES_DELETED).should('exist');
});
awaitToast({ withSSE: true, message: TEXTS.NOTIF_SOURCES_DELETED(5) }, () => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
});
});
});
Expand Down
21 changes: 14 additions & 7 deletions frontend/webapp/cypress/e2e/04-destinations.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deleteEntity, getCrdById, getCrdIds, updateEntity } from '../functions';
import { awaitToast, deleteEntity, getCrdById, getCrdIds, updateEntity } from '../functions';
import { BUTTONS, CRD_NAMES, DATA_IDS, NAMESPACES, ROUTES, SELECTED_ENTITIES, TEXTS } from '../constants';

// The number of CRDs that exist in the cluster before running any tests should be 0.
Expand All @@ -11,7 +11,7 @@ const crdName = CRD_NAMES.DESTINATION;
describe('Destinations CRUD', () => {
beforeEach(() => cy.intercept('/graphql').as('gql'));

it('Should create a CRD in the cluster', () => {
it('Should create a CRD in the cluster, and notify with SSE', () => {
cy.visit(ROUTES.OVERVIEW);

getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 }, () => {
Expand All @@ -23,12 +23,14 @@ describe('Destinations CRUD', () => {
cy.get('button').contains(BUTTONS.DONE).click();

cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 });
awaitToast({ withSSE: true, message: TEXTS.NOTIF_DESTINATIONS_CREATED(1) }, () => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 });
});
});
});
});

it('Should update the CRD in the cluster', () => {
it('Should update the CRD in the cluster, and notify with SSE', () => {
cy.visit(ROUTES.OVERVIEW);

getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, () => {
Expand All @@ -43,15 +45,18 @@ describe('Destinations CRUD', () => {
cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'destinationName', expectedValue: TEXTS.UPDATED_NAME });

awaitToast({ withSSE: true, message: TEXTS.NOTIF_DESTINATIONS_UPDATED(1) }, () => {
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'destinationName', expectedValue: TEXTS.UPDATED_NAME });
});
});
});
},
);
});
});

it('Should delete the CRD from the cluster', () => {
it('Should delete the CRD from the cluster, and notify with SSE', () => {
cy.visit(ROUTES.OVERVIEW);

getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, () => {
Expand All @@ -64,7 +69,9 @@ describe('Destinations CRUD', () => {
},
() => {
cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
awaitToast({ withSSE: true, message: TEXTS.NOTIF_DESTINATIONS_DELETED(1) }, () => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
});
});
},
);
Expand Down
18 changes: 13 additions & 5 deletions frontend/webapp/cypress/e2e/05-actions.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deleteEntity, getCrdById, getCrdIds, updateEntity } from '../functions';
import { awaitToast, deleteEntity, getCrdById, getCrdIds, updateEntity } from '../functions';
import { BUTTONS, CRD_NAMES, DATA_IDS, INPUTS, NAMESPACES, ROUTES, SELECTED_ENTITIES, TEXTS } from '../constants';

// The number of CRDs that exist in the cluster before running any tests should be 0.
Expand All @@ -23,7 +23,10 @@ describe('Actions CRUD', () => {
cy.get('button').contains(BUTTONS.DONE).click();

cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 });
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
awaitToast({ withSSE: false, message: TEXTS.NOTIF_ACTION_CREATED(crdId) });
});
});
});
});
Expand All @@ -43,7 +46,9 @@ describe('Actions CRUD', () => {
cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'actionName', expectedValue: TEXTS.UPDATED_NAME });
awaitToast({ withSSE: false, message: TEXTS.NOTIF_ACTION_UPDATED(crdId) }, () => {
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'actionName', expectedValue: TEXTS.UPDATED_NAME });
});
});
});
},
Expand All @@ -54,7 +59,8 @@ describe('Actions CRUD', () => {
it('Should delete the CRD from the cluster', () => {
cy.visit(ROUTES.OVERVIEW);

getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, () => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
deleteEntity(
{
nodeId: DATA_IDS.ACTION_NODE,
Expand All @@ -63,7 +69,9 @@ describe('Actions CRUD', () => {
},
() => {
cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
awaitToast({ withSSE: false, message: TEXTS.NOTIF_ACTION_DELETED(crdId) }, () => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
});
});
},
);
Expand Down
18 changes: 13 additions & 5 deletions frontend/webapp/cypress/e2e/06-rules.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { deleteEntity, getCrdById, getCrdIds, updateEntity } from '../functions';
import { awaitToast, deleteEntity, getCrdById, getCrdIds, updateEntity } from '../functions';
import { BUTTONS, CRD_NAMES, DATA_IDS, NAMESPACES, ROUTES, SELECTED_ENTITIES, TEXTS } from '../constants';

// The number of CRDs that exist in the cluster before running any tests should be 0.
Expand All @@ -21,7 +21,10 @@ describe('Instrumentation Rules CRUD', () => {
cy.get('button').contains(BUTTONS.DONE).click();

cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 });
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
awaitToast({ withSSE: false, message: TEXTS.NOTIF_INSTRUMENTATION_RULE_CREATED(crdId) });
});
});
});
});
Expand All @@ -41,7 +44,9 @@ describe('Instrumentation Rules CRUD', () => {
cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'ruleName', expectedValue: TEXTS.UPDATED_NAME });
awaitToast({ withSSE: false, message: TEXTS.NOTIF_INSTRUMENTATION_RULE_UPDATED(crdId) }, () => {
getCrdById({ namespace, crdName, crdId, expectedError: '', expectedKey: 'ruleName', expectedValue: TEXTS.UPDATED_NAME });
});
});
});
},
Expand All @@ -52,7 +57,8 @@ describe('Instrumentation Rules CRUD', () => {
it('Should delete the CRD from the cluster', () => {
cy.visit(ROUTES.OVERVIEW);

getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, () => {
getCrdIds({ namespace, crdName, expectedError: '', expectedLength: 1 }, (crdIds) => {
const crdId = crdIds[0];
deleteEntity(
{
nodeId: DATA_IDS.INSTRUMENTATION_RULE_NODE,
Expand All @@ -61,7 +67,9 @@ describe('Instrumentation Rules CRUD', () => {
},
() => {
cy.wait('@gql').then(() => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
awaitToast({ withSSE: false, message: TEXTS.NOTIF_INSTRUMENTATION_RULE_DELETED(crdId) }, () => {
getCrdIds({ namespace, crdName, expectedError: TEXTS.NO_RESOURCES(namespace), expectedLength: 0 });
});
});
},
);
Expand Down
19 changes: 19 additions & 0 deletions frontend/webapp/cypress/functions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,22 @@ export const deleteEntity = ({ nodeId, nodeContains, warnModalTitle, warnModalNo

if (!!callback) callback();
};

interface AwaitToastOptions {
withSSE: boolean;
message: string;
}

export const awaitToast = ({ withSSE, message }: AwaitToastOptions, callback?: () => void) => {
// In case of SSE, we need around 5 seconds to allow the backend to batch a notification.
// We will force 2 seconds, and Cypress will add 4 more seconds, giving us 6 seconds total.
// We don't want to force too much time or we might miss a notification that was sent earlier than expected!

cy.wait(withSSE ? 2000 : 0).then(() => {
cy.get(DATA_IDS.TOAST).contains(message).as('toast-msg');
cy.get('@toast-msg').should('exist');
cy.get('@toast-msg').parent().parent().find(DATA_IDS.TOAST_CLOSE).click();

if (!!callback) callback();
});
};
10 changes: 7 additions & 3 deletions frontend/webapp/reuseable-components/notification-note/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const NotificationNote: React.FC<Props> = ({ type, title, message, action

return (
<Container className={onClose ? 'animated' : ''} $isLeaving={isLeaving} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
<Content $type={type} style={style}>
<Content data-id='toast' $type={type} style={style}>
<StatusIcon />

<TextWrapper $withAction={!!action}>
Expand All @@ -157,9 +157,13 @@ export const NotificationNote: React.FC<Props> = ({ type, title, message, action

{(!!action || !!onClose) && (
<ButtonsWrapper>
{action && <ActionButton onClick={action.onClick}>{action.label}</ActionButton>}
{action && (
<ActionButton data-id='toast-action' onClick={action.onClick}>
{action.label}
</ActionButton>
)}
{onClose && (
<IconButton onClick={() => closeToast({ asSeen: true })}>
<IconButton data-id='toast-close' onClick={() => closeToast({ asSeen: true })}>
<XIcon size={12} />
</IconButton>
)}
Expand Down

0 comments on commit 419f5ea

Please sign in to comment.