diff --git a/opencti-platform/opencti-front/playwright.config.ts b/opencti-platform/opencti-front/playwright.config.ts index 7d8192aa1dbc..e7f7895193a4 100644 --- a/opencti-platform/opencti-front/playwright.config.ts +++ b/opencti-platform/opencti-front/playwright.config.ts @@ -46,7 +46,7 @@ export default defineConfig({ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', screenshot: 'only-on-failure', - video: 'on-first-retry', + video: 'retain-on-failure', ignoreHTTPSErrors: true, }, expect: { timeout: 60000 }, diff --git a/opencti-platform/opencti-front/src/private/components/analyses/MalwareAnalyses.tsx b/opencti-platform/opencti-front/src/private/components/analyses/MalwareAnalyses.tsx index 44677f477568..f27284d032f3 100644 --- a/opencti-platform/opencti-front/src/private/components/analyses/MalwareAnalyses.tsx +++ b/opencti-platform/opencti-front/src/private/components/analyses/MalwareAnalyses.tsx @@ -167,6 +167,7 @@ const MalwareAnalyses: FunctionComponent = () => { {queryRef && ( +
data.malwareAnalyses?.edges?.map((n) => n?.node)} @@ -177,11 +178,12 @@ const MalwareAnalyses: FunctionComponent = () => { lineFragment={malwareAnalysisFragment} exportContext={{ entity_type: 'Malware-Analysis' }} createButton={isFABReplaced && ( - - - + + + )} /> +
)} {!isFABReplaced && ( diff --git a/opencti-platform/opencti-front/src/private/components/analyses/groupings/Grouping.jsx b/opencti-platform/opencti-front/src/private/components/analyses/groupings/Grouping.jsx index 0f16d873a8d8..dc864265a029 100644 --- a/opencti-platform/opencti-front/src/private/components/analyses/groupings/Grouping.jsx +++ b/opencti-platform/opencti-front/src/private/components/analyses/groupings/Grouping.jsx @@ -31,7 +31,7 @@ const GroupingComponent = ({ grouping }) => { const { canEdit } = useGetCurrentUserAccessRight(grouping.currentUserAccessRight); return ( -
+
{mode !== 'graph' && ( +
{t_i18n('Details')} diff --git a/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectHistory.jsx b/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectHistory.jsx index 26048ead457c..8b491d20c2f8 100644 --- a/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectHistory.jsx +++ b/opencti-platform/opencti-front/src/private/components/common/stix_core_objects/StixCoreObjectHistory.jsx @@ -41,6 +41,7 @@ class StixCoreObjectHistory extends Component { container={true} spacing={3} classes={{ container: classes.gridContainer }} + data-testid='sco-history-content' > { const stixDomainObjectContentTab = new StixDomainObjectContentTabPage(page); // go to groupings - await page.goto('/dashboard/analyses/groupings'); + await groupingsPage.goto(); await expect(groupingsPage.getPage()).toBeVisible(); // add a new grouping await groupingsPage.addNew(); @@ -20,7 +20,7 @@ test('Create a new grouping', async ({ page }) => { await groupingForm.submit(); // open it await groupingsPage.getItemFromList('Test grouping e2e').click(); - await expect(groupingDetails.getGroupingDetailsPage()).toBeVisible(); + await expect(groupingDetails.getPage()).toBeVisible(); await expect(groupingDetails.getTitle('Test grouping e2e')).toBeVisible(); // add content await groupingDetails.goToTab('Content'); diff --git a/opencti-platform/opencti-front/tests_e2e/model/MalwareAnalyses.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/MalwareAnalyses.pageModel.ts new file mode 100644 index 000000000000..25ea10f567d8 --- /dev/null +++ b/opencti-platform/opencti-front/tests_e2e/model/MalwareAnalyses.pageModel.ts @@ -0,0 +1,30 @@ +import { Page } from '@playwright/test'; +import LeftBarPage from './menu/leftBar.pageModel'; + +export default class MalwareAnalysesPage { + pageUrl = '/dashboard/analyses/malware_analyses'; + + constructor(private page: Page) { + } + + /** + * Reload the page (like F5), mostly used once on test start. + * When possible please use navigateFromMenu instead it's faster. + */ + async goto() { + await this.page.goto(this.pageUrl); + } + + async navigateFromMenu() { + const leftBarPage = new LeftBarPage(this.page); + await leftBarPage.open(); + await leftBarPage.clickOnMenu('Analyses', 'Malware analyses'); + } + getPage() { + return this.page.getByTestId('malware-analyses-page'); + } + + getItemFromList(name: string) { + return this.page.getByLabel(name); + } +} diff --git a/opencti-platform/opencti-front/tests_e2e/model/MalwareAnalysesDetails.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/MalwareAnalysesDetails.pageModel.ts new file mode 100644 index 000000000000..64fbcbff407e --- /dev/null +++ b/opencti-platform/opencti-front/tests_e2e/model/MalwareAnalysesDetails.pageModel.ts @@ -0,0 +1,11 @@ +import { Page } from '@playwright/test'; +import SDOTabs from './SDOTabs.pageModel'; + +export default class MalwareAnalysesDetailsPage { + tabs = new SDOTabs(this.page); + constructor(private page: Page) {} + + getPage() { + return this.page.getByTestId('malware-analyses-details-page'); + } +} diff --git a/opencti-platform/opencti-front/tests_e2e/model/SDOTabs.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/SDOTabs.pageModel.ts new file mode 100644 index 000000000000..aa945921b790 --- /dev/null +++ b/opencti-platform/opencti-front/tests_e2e/model/SDOTabs.pageModel.ts @@ -0,0 +1,36 @@ +import { Page } from '@playwright/test'; + +/** + * Common page for all components that have Overview/Knowledge/...etc tabs (in knowledge) + */ +export default class SDOTabs { + constructor(private page: Page) {} + + goToOverviewTab() { + return this.page.getByRole('tab', { name: 'Overview' }).click(); + } + + goToKnowledgeTab() { + return this.page.getByRole('tab', { name: 'Knowledge' }).click(); + } + + goToEntitiesTab() { + return this.page.getByRole('tab', { name: 'Entities' }).click(); + } + + goToContentTab() { + return this.page.getByRole('tab', { name: 'Content' }).click(); + } + + goToDataTab() { + return this.page.getByRole('tab', { name: 'Data' }).click(); + } + + goToObservablesTab() { + return this.page.getByRole('tab', { name: 'Observables' }).click(); + } + + goToHistoryTab() { + return this.page.getByRole('tab', { name: 'History' }).click(); + } +} diff --git a/opencti-platform/opencti-front/tests_e2e/model/StixCoreObjectHistoryTab.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/StixCoreObjectHistoryTab.pageModel.ts new file mode 100644 index 000000000000..91764893dc4f --- /dev/null +++ b/opencti-platform/opencti-front/tests_e2e/model/StixCoreObjectHistoryTab.pageModel.ts @@ -0,0 +1,10 @@ +import { Page } from '@playwright/test'; + +export default class StixCoreObjectHistoryTab { + constructor(private page: Page) { + } + + getPage() { + return this.page.getByTestId('sco-history-content'); + } +} diff --git a/opencti-platform/opencti-front/tests_e2e/model/grouping.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/grouping.pageModel.ts index 8afbb384d957..89fc6faae80a 100644 --- a/opencti-platform/opencti-front/tests_e2e/model/grouping.pageModel.ts +++ b/opencti-platform/opencti-front/tests_e2e/model/grouping.pageModel.ts @@ -1,8 +1,24 @@ import { Page } from '@playwright/test'; +import LeftBarPage from './menu/leftBar.pageModel'; export default class GroupingsPage { + pageUrl = '/dashboard/analyses/groupings'; constructor(private page: Page) {} + /** + * Reload the page (like F5), mostly used once on test start. + * When possible please use navigateFromMenu instead it's faster. + */ + async goto() { + await this.page.goto(this.pageUrl); + } + + async navigateFromMenu() { + const leftBarPage = new LeftBarPage(this.page); + await leftBarPage.open(); + await leftBarPage.clickOnMenu('Analyses', 'Groupings'); + } + getPage() { return this.page.getByTestId('groupings-page'); } @@ -20,7 +36,7 @@ export default class GroupingsPage { } getCreateButton() { - return this.page.getByRole('button', { name: 'Create Grouping' }) + return this.page.getByRole('button', { name: 'Create Grouping' }); } getItemFromList(name: string) { diff --git a/opencti-platform/opencti-front/tests_e2e/model/groupingDetails.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/groupingDetails.pageModel.ts index c11efb71978b..2967e87f1a2b 100644 --- a/opencti-platform/opencti-front/tests_e2e/model/groupingDetails.pageModel.ts +++ b/opencti-platform/opencti-front/tests_e2e/model/groupingDetails.pageModel.ts @@ -1,9 +1,11 @@ import { Page } from '@playwright/test'; +import SDOTabs from './SDOTabs.pageModel'; export default class GroupingDetailsPage { + tabs = new SDOTabs(this.page); constructor(private page: Page) {} - getGroupingDetailsPage() { + getPage() { return this.page.getByTestId('grouping-details-page'); } diff --git a/opencti-platform/opencti-front/tests_e2e/model/report.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/report.pageModel.ts index 693bbf246b64..c32bbdeb188a 100644 --- a/opencti-platform/opencti-front/tests_e2e/model/report.pageModel.ts +++ b/opencti-platform/opencti-front/tests_e2e/model/report.pageModel.ts @@ -1,13 +1,24 @@ import { Page } from '@playwright/test'; +import LeftBarPage from './menu/leftBar.pageModel'; export default class ReportPage { pageUrl = '/dashboard/analyses/reports'; constructor(private page: Page) {} + /** + * Reload the page (like F5), mostly used once on test start. + * When possible please use navigateFromMenu instead it's faster. + */ async goto() { await this.page.goto(this.pageUrl); } + async navigateFromMenu() { + const leftBarPage = new LeftBarPage(this.page); + await leftBarPage.open(); + await leftBarPage.clickOnMenu('Analyses', 'Reports'); + } + getPage() { return this.page.getByTestId('report-page'); } diff --git a/opencti-platform/opencti-front/tests_e2e/model/reportDetails.pageModel.ts b/opencti-platform/opencti-front/tests_e2e/model/reportDetails.pageModel.ts index 2099c4fd6b83..b9e7ec12e556 100644 --- a/opencti-platform/opencti-front/tests_e2e/model/reportDetails.pageModel.ts +++ b/opencti-platform/opencti-front/tests_e2e/model/reportDetails.pageModel.ts @@ -1,8 +1,10 @@ import { Page } from '@playwright/test'; import AutocompleteFieldPageModel from './field/AutocompleteField.pageModel'; +import SDOTabs from './SDOTabs.pageModel'; export default class ReportDetailsPage { labelsSelect = new AutocompleteFieldPageModel(this.page, 'Labels', true); + tabs = new SDOTabs(this.page); constructor(private page: Page) {} @@ -18,34 +20,10 @@ export default class ReportDetailsPage { return this.page.getByLabel('Update', { exact: true }); } - async goToOverviewTab() { - await this.page.getByRole('tab', { name: 'Overview' }).click(); - } - - goToKnowledgeTab() { - return this.page.getByRole('tab', { name: 'Knowledge' }).click(); - } - - goToEntitiesTab() { - return this.page.getByRole('tab', { name: 'Entities' }).click(); - } - - goToContentTab() { - return this.page.getByRole('tab', { name: 'Content' }).click(); - } - - goToDataTab() { - return this.page.getByRole('tab', { name: 'Data' }).click(); - } - getContentFile(fileName: string) { return this.page.getByLabel(fileName); } - goToObservablesTab() { - return this.page.getByRole('tab', { name: 'Observables' }).click(); - } - getTextForHeading(heading: string, text: string) { return this.page .getByRole('heading', { name: heading }) diff --git a/opencti-platform/opencti-front/tests_e2e/navigation/navigation.spec.ts b/opencti-platform/opencti-front/tests_e2e/navigation/navigation.spec.ts index 47f2d9d515fe..8d8388b61d24 100644 --- a/opencti-platform/opencti-front/tests_e2e/navigation/navigation.spec.ts +++ b/opencti-platform/opencti-front/tests_e2e/navigation/navigation.spec.ts @@ -6,6 +6,99 @@ import ReportDetailsPage from '../model/reportDetails.pageModel'; import StixDomainObjectContentTabPage from '../model/StixDomainObjectContentTab.pageModel'; import ContainerObservablesPage from '../model/containerObservables.pageModel'; import StixCoreObjectDataTab from '../model/StixCoreObjectDataTab.pageModel'; +import GroupingsPage from '../model/grouping.pageModel'; +import GroupingDetailsPage from '../model/groupingDetails.pageModel'; +import MalwareAnalysesPage from '../model/MalwareAnalyses.pageModel'; +import MalwareAnalysesDetailsPage from '../model/MalwareAnalysesDetails.pageModel'; +import StixCoreObjectHistoryTab from '../model/StixCoreObjectHistoryTab.pageModel'; + +/** + * Goal: validate that everything is opening wihtout errors in Analyses > Malware analyses. + * @param page + */ +const navigateMalwareAnalyses = async (page: Page) => { + const malwareAnalysesNameFromInitData = 'Spelevo EK analysis'; + const malwareAnalysesPage = new MalwareAnalysesPage(page); + await malwareAnalysesPage.navigateFromMenu(); + + await expect(malwareAnalysesPage.getPage()).toBeVisible(); + await expect(page.getByText(malwareAnalysesNameFromInitData)).toBeVisible(); + await malwareAnalysesPage.getItemFromList(malwareAnalysesNameFromInitData).click(); + + const malwareAnalysesDetailsPage = new MalwareAnalysesDetailsPage(page); + await expect(malwareAnalysesDetailsPage.getPage()).toBeVisible(); + + // -- Knowledge + await malwareAnalysesDetailsPage.tabs.goToKnowledgeTab(); + await expect(page.getByPlaceholder('Search these results...')).toBeVisible(); + await page.getByLabel('relationships', { exact: true }).click(); + await expect(page.getByRole('link', { name: 'related to Malware Spelevo EK' })).toBeVisible(); + await page.getByLabel('entities', { exact: true }).click(); + await expect(page.getByRole('link', { name: 'Malware Spelevo EK admin ryuk' })).toBeVisible(); + + // -- Content + await malwareAnalysesDetailsPage.tabs.goToContentTab(); + const contentTab = new StixDomainObjectContentTabPage(page); + await expect(contentTab.getPage()).toBeVisible(); + + // -- Data + await malwareAnalysesDetailsPage.tabs.goToDataTab(); + await expect(page.getByRole('heading', { name: 'Uploaded files' })).toBeVisible(); + + // -- History + await malwareAnalysesDetailsPage.tabs.goToHistoryTab(); + const historyTab = new StixCoreObjectHistoryTab(page); + await expect(historyTab.getPage()).toBeVisible(); +}; + +/** + * Goal: validate that everything is opening wihtout errors in Analyses > Grouping. + * @param page + */ +const navigateGroupings = async (page: Page) => { + const groupingsNameFromInitData = 'Navigation test grouping entity'; + + const groupingPage = new GroupingsPage(page); + await groupingPage.navigateFromMenu(); + await expect(groupingPage.getPage()).toBeVisible(); + await expect(page.getByText(groupingsNameFromInitData)).toBeVisible(); + await groupingPage.getItemFromList(groupingsNameFromInitData).click(); + + const groupingsDetailsPage = new GroupingDetailsPage(page); + await expect(groupingsDetailsPage.getPage()).toBeVisible(); + + // -- Knowledge + await groupingsDetailsPage.tabs.goToKnowledgeTab(); + await expect(page.getByTestId('groupings-knowledge')).toBeVisible(); + await page.getByLabel('Correlation view').click(); + await page.getByLabel('Tactics matrix view').click(); + await page.getByLabel('Graph view').click(); + + // -- Content + await groupingsDetailsPage.tabs.goToContentTab(); + const contentTab = new StixDomainObjectContentTabPage(page); + await expect(contentTab.getPage()).toBeVisible(); + await contentTab.getContentMappingViewButton().click(); + await expect(page.getByRole('button', { name: 'Clear mappings' })).toBeVisible(); + await contentTab.getContentViewButton().click(); + await expect(page.getByText('Description', { exact: true })).toBeVisible(); + await expect(page.getByText('Mappable content')).toBeVisible(); + + // -- Entities + await groupingsDetailsPage.tabs.goToEntitiesTab(); + await expect(page.getByText('Entity types')).toBeVisible(); + await expect(page.getByText('Add entity')).toBeVisible(); + + // -- Artifact / Observables + await groupingsDetailsPage.tabs.goToObservablesTab(); + const observablesTab = new ContainerObservablesPage(page); + await expect(observablesTab.getPage()).toBeVisible(); + + // -- Data + await groupingsDetailsPage.tabs.goToDataTab(); + const dataTab = new StixCoreObjectDataTab(page); + await expect(dataTab.getPage()).toBeVisible(); +}; /** * Goal: validate that everything is opening without errors @@ -25,7 +118,7 @@ const navigateReports = async (page: Page) => { const reportNameFromInitData = 'E2E dashboard - Report - now'; const reportPage = new ReportPage(page); - await reportPage.goto(); + await reportPage.navigateFromMenu(); await expect(reportPage.getPage()).toBeVisible(); await expect(page.getByText(reportNameFromInitData)).toBeVisible(); await reportPage.getItemFromList(reportNameFromInitData).click(); @@ -34,7 +127,7 @@ const navigateReports = async (page: Page) => { await expect(reportDetailsPage.getPage()).toBeVisible(); // -- Knowledge - await reportDetailsPage.goToKnowledgeTab(); + await reportDetailsPage.tabs.goToKnowledgeTab(); await expect(page.getByTestId('report-knowledge')).toBeVisible(); await page.getByLabel('TimeLine view').click(); await page.getByLabel('Correlation view').click(); @@ -42,7 +135,7 @@ const navigateReports = async (page: Page) => { await page.getByLabel('Graph view').click(); // -- Content - await reportDetailsPage.goToContentTab(); + await reportDetailsPage.tabs.goToContentTab(); const contentTab = new StixDomainObjectContentTabPage(page); await expect(contentTab.getPage()).toBeVisible(); await contentTab.getContentMappingViewButton().click(); @@ -52,25 +145,23 @@ const navigateReports = async (page: Page) => { await expect(page.getByText('Mappable content')).toBeVisible(); // -- Entities - await reportDetailsPage.goToEntitiesTab(); + await reportDetailsPage.tabs.goToEntitiesTab(); await expect(page.getByText('Entity types')).toBeVisible(); await expect(page.getByText('Add entity')).toBeVisible(); // -- Artifact / Observables - await reportDetailsPage.goToObservablesTab(); + await reportDetailsPage.tabs.goToObservablesTab(); const observablesTab = new ContainerObservablesPage(page); await expect(observablesTab.getPage()).toBeVisible(); // -- Data - await reportDetailsPage.goToDataTab(); + await reportDetailsPage.tabs.goToDataTab(); const dataTab = new StixCoreObjectDataTab(page); await expect(dataTab.getPage()).toBeVisible(); }; const navigateAllMenu = async (page: Page) => { - await page.goto('/'); const leftBarPage = new LeftBarPage(page); - await leftBarPage.open(); // Checking Analyses menu await leftBarPage.clickOnMenu('Analyses', 'Reports'); @@ -208,6 +299,15 @@ const navigateAllMenu = async (page: Page) => { }; test('Check navigation on all pages', { tag: ['@navigation'] }, async ({ page }) => { + await page.goto('/'); + const leftBarPage = new LeftBarPage(page); + await leftBarPage.open(); + + // For faster debugging, each navigated can be commented. + // so they should be all independent and start from the left menu. + await navigateAllMenu(page); await navigateReports(page); + await navigateGroupings(page); + await navigateMalwareAnalyses(page); }); diff --git a/opencti-platform/opencti-front/tests_e2e/report/report.spec.ts b/opencti-platform/opencti-front/tests_e2e/report/report.spec.ts index b27ab42b86d3..b2a828adaeec 100644 --- a/opencti-platform/opencti-front/tests_e2e/report/report.spec.ts +++ b/opencti-platform/opencti-front/tests_e2e/report/report.spec.ts @@ -35,6 +35,7 @@ test('Report CRUD', { tag: ['@report', '@knowledge', '@mutation'] }, async ({ pa const reportForm = new ReportFormPage(page); await reportPage.goto(); + await reportPage.navigateFromMenu(); // open nav bar once and for all await leftNavigation.open(); @@ -187,7 +188,7 @@ test('Report CRUD', { tag: ['@report', '@knowledge', '@mutation'] }, async ({ pa const historyDate = reportDetailsPage.getTextForHeading('Most recent history', format(new Date(), 'MMM d, yyyy')); await expect(historyDate).toBeVisible(); - await reportDetailsPage.goToDataTab(); + await reportDetailsPage.tabs.goToDataTab(); const file = reportDetailsPage.getTextForHeading('UPLOADED FILES', 'report.test.md'); await expect(file).toBeVisible(); @@ -197,7 +198,7 @@ test('Report CRUD', { tag: ['@report', '@knowledge', '@mutation'] }, async ({ pa // region Update the report // ------------------------ - await reportDetailsPage.goToOverviewTab(); + await reportDetailsPage.tabs.goToOverviewTab(); await expect(page.getByTestId('report-overview')).toBeVisible(); const reportNameUpdate = `Report updated - ${uuid()}`; @@ -396,7 +397,7 @@ test('Report live entities creation and relationships', { tag: ['@report', '@kno // region Manipulate entities on Entities tab // ------------------------------------------ - await reportDetailsPage.goToEntitiesTab(); + await reportDetailsPage.tabs.goToEntitiesTab(); await entitiesTab.clickAddEntities(); await entitiesTab.search('note'); await entitiesTab.addEntity('This is a note'); diff --git a/opencti-platform/opencti-graphql/package.json b/opencti-platform/opencti-graphql/package.json index aba8b692e660..798fcdd49762 100644 --- a/opencti-platform/opencti-graphql/package.json +++ b/opencti-platform/opencti-graphql/package.json @@ -15,7 +15,7 @@ "lint": "cross-env DEBUG=eslint:cli-engine TIMING=1 eslint --max-warnings 0 --cache -c .eslintrc.js src", "build": "yarn install:python && yarn build:prod", "start": "NODE_ENV=dev yarn build:dev && node build/back.js", - "start:e2e": "NODE_ENV=dev yarn build:dev && EXPIRATION_SCHEDULER__ENABLED=false REDIS__NAMESPACE=e2e-start RABBITMQ__QUEUE_PREFIX=e2e MINIO__BUCKET_NAME=e2e-start-bucket ELASTICSEARCH__INDEX_PREFIX=e2e-start node build/back.js", + "start:e2e": "NODE_ENV=dev yarn build:dev && APP__DISABLED_DEV_FEATURES='[]' EXPIRATION_SCHEDULER__ENABLED=false REDIS__NAMESPACE=e2e-start RABBITMQ__QUEUE_PREFIX=e2e MINIO__BUCKET_NAME=e2e-start-bucket ELASTICSEARCH__INDEX_PREFIX=e2e-start node build/back.js", "start:light": "NODE_ENV=dev node build/back.js", "start:cluster": "NODE_ENV=cluster node build/back.js", "serv": "node build/back.js", diff --git a/opencti-platform/opencti-graphql/tests/data/data-test-stix-e2e.json b/opencti-platform/opencti-graphql/tests/data/data-test-stix-e2e.json index a43a54c3efaa..43bcad0c311a 100644 --- a/opencti-platform/opencti-graphql/tests/data/data-test-stix-e2e.json +++ b/opencti-platform/opencti-graphql/tests/data/data-test-stix-e2e.json @@ -902,6 +902,19 @@ "x_opencti_id": "057e0f4e-34cf-45c5-bef4-cfc3cf5ae4ec", "x_opencti_type": "Incident", "type": "incident" + }, + { + "id": "grouping--1d2cb936-0259-52f6-ac06-dcb8f5536732", + "spec_version": "2.1", + "revoked": false, + "confidence": 100, + "created": "2024-07-30T13:15:37.447Z", + "modified": "2024-07-30T13:15:37.447Z", + "name": "Navigation test grouping entity", + "context": "unspecified", + "x_opencti_id": "91bced0e-63dc-4ea6-ab6d-7137706b1d87", + "x_opencti_type": "Grouping", + "type": "grouping" } ] } \ No newline at end of file