Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added .cypress/.DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,6 @@ import {

import { suppressResizeObserverIssue } from '../utils/constants';

const moveToEventsHome = () => {
cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/event_analytics/`);
cy.wait(delay * 3);
};

const moveToPanelHome = () => {
cy.visit(
`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
);
cy.wait(delay * 3);
};

const moveToTestPanel = () => {
moveToPanelHome();
cy.get('.euiTableCellContent').contains(TEST_PANEL).trigger('mouseover').click();
cy.wait(delay * 3);
cy.get('h1').contains(TEST_PANEL).should('exist');
};

describe('Adding sample data and visualization', () => {
it('Adds sample flights data for visualization paragraph', () => {
Expand Down Expand Up @@ -96,44 +78,78 @@ describe('Creating visualizations', () => {
});
});

describe('Testing panels table', () => {
describe.only('Testing panels table', () => {
beforeEach(() => {
moveToPanelHome();
eraseTestPanels();
});

it('Displays error toast for invalid panel name', () => {
cy.get('button[data-test-subj="customPanels__createNewPanels"]').click();
cy.get('button[data-test-subj="runModalButton"]').click();
cy.get('.euiToastHeader__title').contains('Invalid Operational Panel name').should('exist');
clickCreatePanelButton();
confirmModal();
expectToastWith('Invalid Operational Panel name');
});

it('Creates a panel and redirects to the panel', () => {
cy.get('button[data-test-subj="customPanels__createNewPanels"]').click();
clickCreatePanelButton();
cy.get('input.euiFieldText').focus().type(TEST_PANEL, {
delay: 50,
});
cy.get('button[data-test-subj="runModalButton"]').click();
cy.contains(TEST_PANEL).should('exist');
});

it('Duplicates a panel', () => {
cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).trigger('mouseover').click();
cy.get('button[data-test-subj="operationalPanelsActionsButton"]').click();
it('Duplicates a legacy panel', () => {
createLegacyPanel()
selectThePanel();
openActionsDropdown();
cy.get('button[data-test-subj="duplicateContextMenuItem"]').click();
cy.get('button[data-test-subj="runModalButton"]').click();
cy.contains(TEST_PANEL + " (copy)").should('exist');
const duplicate = testPanelTableCell()
expectUuid(duplicate)
});

it('Renames a panel', () => {
cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).trigger('mouseover').click();
cy.get('button[data-test-subj="operationalPanelsActionsButton"]').click();
it.only('Duplicates a legacy panel', () => {
createLegacyPanel()
selectThePanel();
openActionsDropdown();
cy.get('button[data-test-subj="duplicateContextMenuItem"]').click();
cy.get('button[data-test-subj="runModalButton"]').click();
cy.contains(TEST_PANEL + " (copy)").should('exist');
const duplicate = testPanelTableCell()
expectUuid(duplicate)
});

it('Renames a saved-objects panel', () => {
createSavedObjectPanel()
cy.reload()

selectThePanel()
openActionsDropdown();
cy.get('button[data-test-subj="renameContextMenuItem"]').click();
cy.get('input.euiFieldText').focus().type(' (rename)', {
delay: 50,
});
cy.get('button[data-test-subj="runModalButton"]').click();
});

it('Renames a panel', () => {
createLegacyPanel();
cy.reload();
const cell = cy.get('.euiTableCellContent')
expectLegacyId(cell);
selectThePanel()
openActionsDropdown();
cy.get('button[data-test-subj="renameContextMenuItem"]').click();
cy.get('input.euiFieldText').focus().type(' (rename)');
cy.get('button[data-test-subj="runModalButton"]').click();
const renamed = testPanelTableCell()
expectUuid(renamed)
});

it('Searches existing panel', () => {
createLegacyPanel()
cy.get('input[data-test-subj="operationalPanelSearchBar"]')
.focus()
.type('this panel should not exist', {
Expand All @@ -154,9 +170,24 @@ describe('Testing panels table', () => {
.should('exist');
});

it('Deletes saved object panels', () => {
createSavedObjectPanel()
cy.get('input[data-test-subj="checkboxSelectAll"]').click();
openActionsDropdown();
cy.get('button[data-test-subj="deleteContextMenuItem"]').click();
cy.get('button[data-test-subj="popoverModal__deleteButton"]').should('be.disabled');

cy.get('input.euiFieldText[placeholder="delete"]').focus().type('delete', {
delay: 50,
});
cy.get('button[data-test-subj="popoverModal__deleteButton"]').should('not.be.disabled');
cy.get('button[data-test-subj="popoverModal__deleteButton"]').click();
cy.get('h2[data-test-subj="customPanels__noPanelsHome"]').should('exist');
});

it('Deletes panels', () => {
cy.get('input[data-test-subj="checkboxSelectAll"]').click();
cy.get('button[data-test-subj="operationalPanelsActionsButton"]').click();
openActionsDropdown();
cy.get('button[data-test-subj="deleteContextMenuItem"]').click();
cy.get('button[data-test-subj="popoverModal__deleteButton"]').should('be.disabled');

Expand All @@ -170,7 +201,7 @@ describe('Testing panels table', () => {

it('Create a panel for testing', () => {
// keep a panel for testing
cy.get('button[data-test-subj="customPanels__createNewPanels"]').click();
clickCreatePanelButton();
cy.get('input.euiFieldText').focus().type(TEST_PANEL, {
delay: 50,
});
Expand Down Expand Up @@ -470,8 +501,8 @@ describe('Clean up all test data', () => {
it('Deletes test panel', () => {
moveToPanelHome();
cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').trigger('mouseover').click();
cy.get('button[data-test-subj="operationalPanelsActionsButton"]').click();
cy.get('button[data-test-subj="deleteContextMenuItem"]').click();
openActionsDropdown();
clickDeleteAction();
cy.get('button.euiButton--danger').should('be.disabled');
cy.get('input.euiFieldText[placeholder="delete"]').focus().type('delete', {
delay: 50,
Expand All @@ -482,3 +513,169 @@ describe('Clean up all test data', () => {
cy.get('.euiTextAlign').contains('No Operational Panels').should('exist');
});
});


const moveToEventsHome = () => {
cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/event_analytics/`);
cy.wait(delay * 3);
};

const moveToPanelHome = () => {
cy.visit(
`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/operational_panels/`
, { timeout: 3000 });
cy.wait(delay * 3);
};

const testPanelTableCell = () => cy.get('.euiTableCellContent').contains(TEST_PANEL)

const moveToTestPanel = () => {
moveToPanelHome();
testPanelTableCell().trigger('mouseover').click();
cy.wait(delay * 3);
cy.get('h1').contains(TEST_PANEL).should('exist');
};

const TEST_PANEL_RX = new RegExp(TEST_PANEL + '.*')

const eraseLegacyPanels = () => {

cy.request({
method: 'GET',
failOnStatusCode: false,
url: 'api/observability/operational_panels/panels',
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
},
}).then((response) => {
response.body.panels
.map(panel => {
cy.request({
method: 'DELETE',
failOnStatusCode: false,
url: `api/observability/operational_panels/panels/${panel.id}`,
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
}
}).then(response => {
const deletedId = response.allRequestResponses[0]['Request URL'].split('/').slice(-1)
console.log("erased panel", deletedId)
})
}
)
}
)
}

const eraseSavedObjectPaenls = () => {
return cy.request({
method: 'get',
failOnStatusCode: false,
url: 'api/saved_objects/_find?type=observability-panel',
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
}
}).then(response => {
response.body.saved_objects
.map(soPanel => {
cy.request({
method: 'DELETE',
failOnStatusCode: false,
url: `api/saved_objects/observability-panel/${soPanel.id}`,
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
}
})
})
})
}

const eraseTestPanels = () => {
eraseLegacyPanels()
eraseSavedObjectPaenls()

}
const uuidRx = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;

const clickCreatePanelButton = () => cy.get('a[data-test-subj="customPanels__createNewPanels"]').click();

const createSavedObjectPanel = () => {
const result = cy.request({
method: 'POST',
failOnStatusCode: false,
url: 'api/saved_objects/observability-panel',
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
},
body: {
"attributes": {
"title": TEST_PANEL,
"description": "",
"dateCreated": 1681127334085,
"dateModified": 1681127334085,
"timeRange": {
"to": "now",
"from": "now-1d"
},
"queryFilter": {
"query": "",
"language": "ppl"
},
"visualizations": [],
"applicationId": ""
}
}
}).then(response => console.log(response))

}

const createLegacyPanel = () => {
const result = cy.request({
method: 'POST',
failOnStatusCode: false,
url: 'api/observability/operational_panels/panels',
headers: {
'content-type': 'application/json;charset=UTF-8',
'osd-xsrf': true,
},
body: { panelName: TEST_PANEL }
})
}

const expectUuid = (cell) => {
cell.find('a').its('href').should('match', uuidRx)
// const id = url.split('/').slice(-1)
// expect(id).not.to.match(uuidRx)
}

const expectLegacyId = (cell) => {
cell.find('a').its('href').should('not.match', uuidRx)
// const id = url.split('/').slice(-1)
// expect(id).not.to.match(uuidRx)
}

const clickDeleteAction = () => {
cy.get('button[data-test-subj="deleteContextMenuItem"]').click();
}

const openActionsDropdown = () => {
cy.get('button[data-test-subj="operationalPanelsActionsButton"]').click();
}

const selectThePanel = () => {
cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).trigger('mouseover').click();
}

const expectToastWith = (title) => {
cy.get('.euiToastHeader__title').contains(title).should('exist');
}

const confirmModal = () => {
cy.get('button[data-test-subj="runModalButton"]').click();
}

4 changes: 4 additions & 0 deletions .cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)


/**
* @type {Cypress.PluginConfig}
*/
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
require('cypress-watch-and-reload/plugins')(config)

return config
}
2 changes: 2 additions & 0 deletions .cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
// https://on.cypress.io/configuration
// ***********************************************************

import 'cypress-watch-and-reload/support'

// Import commands.js using ES2015 syntax:
import './commands';

Expand Down
7 changes: 6 additions & 1 deletion common/constants/custom_panels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,10 @@
*/

export const CUSTOM_PANELS_API_PREFIX = '/api/observability/operational_panels';
export const CUSTOM_PANELS_DOCUMENTATION_URL = 'https://opensearch.org/docs/latest/observability-plugin/operational-panels/';
export const CUSTOM_PANELS_DOCUMENTATION_URL =
'https://opensearch.org/docs/latest/observability-plugin/operational-panels/';
export const CREATE_PANEL_MESSAGE = 'Enter a name to describe the purpose of this custom panel.';

export const CUSTOM_PANELS_SAVED_OBJECT_TYPE = 'observability-panel';

export const CUSTOM_PANEL_SLICE = 'customPanel';
Loading