diff --git a/.cypress/integration/notebooks_test/notebooks.spec.js b/.cypress/integration/notebooks_test/notebooks.spec.js index e23d706673..5501616968 100644 --- a/.cypress/integration/notebooks_test/notebooks.spec.js +++ b/.cypress/integration/notebooks_test/notebooks.spec.js @@ -6,7 +6,6 @@ /// import { - delay, TEST_NOTEBOOK, MARKDOWN_TEXT, SAMPLE_URL, @@ -14,13 +13,8 @@ import { PPL_QUERY_TEXT, NOTEBOOK_TEXT, OPENSEARCH_URL, - COMMAND_TIMEOUT_LONG, } from '../../utils/constants'; -import { SAMPLE_PANEL } from '../../utils/panel_constants'; - -import { skipOn } from '@cypress/skip-test'; - import { v4 as uuid4 } from 'uuid'; const moveToEventsHome = () => { @@ -31,10 +25,18 @@ const moveToPanelHome = () => { cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-dashboards#/`); }; +const moveToNotebookHome = () => { + cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-notebooks#/`); +}; + const moveToTestNotebook = () => { cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-notebooks#/`, { timeout: 6000, }); + + // Reload page to load notebooks if they are not flushed in OpenSearch index yet. + cy.reload(); + cy.get('.euiTableCellContent') .contains(TEST_NOTEBOOK, { timeout: 6000, @@ -66,52 +68,55 @@ describe('Adding sample data and visualization', () => { describe('Testing notebooks table', () => { beforeEach(() => { - cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-notebooks#/`); + moveToNotebookHome(); }); it('Notebooks table empty state', () => { - cy.get('#notebookArea').contains('Notebooks (0)').should('exist'); - cy.get('.euiTextAlign.euiTextAlign--center').contains('No notebooks'); - cy.get('.euiButton__text').eq(2).contains('Create notebook'); - cy.get('.euiButton__text').eq(3).contains('Add samples'); + cy.get('h3[data-test-subj="notebookTableTitle"]').contains('Notebooks (0)').should('exist'); + cy.get('div[data-test-subj="notebookEmptyTableText"]').contains('No notebooks'); + cy.get('a[data-test-subj="notebookEmptyTableCreateBtn"]').contains('Create notebook'); + cy.get('button[data-test-subj="notebookEmptyTableAddSamplesBtn"]').contains('Add samples'); }); it('Displays error toast for invalid notebook name', () => { - cy.get('.euiButton__text').contains('Create notebook').click(); - cy.get('.euiButton__text') - .contains(/^Create$/) - .click(); - cy.get('.euiToastHeader__title').contains('Invalid notebook name').should('exist'); + cy.get('a[data-test-subj="createNotebookPrimaryBtn"]').click(); + cy.get('button[data-test-subj="custom-input-modal-confirm-button"]').click(); + cy.get('div[data-test-subj="euiToastHeader"]') + .contains('Invalid notebook name') + .should('exist'); }); it('Creates a notebook and redirects to the notebook', () => { - cy.get('.euiButton__text').contains('Create notebook').click(); - cy.get('input.euiFieldText').type(TEST_NOTEBOOK); - cy.get('.euiButton__text') - .contains(/^Create$/) - .click(); + cy.get('a[data-test-subj="createNotebookPrimaryBtn"]').click(); + cy.get('input[data-test-subj="custom-input-modal-input"]').focus().type(TEST_NOTEBOOK); + cy.get('button[data-test-subj="custom-input-modal-confirm-button"]').click(); cy.contains(TEST_NOTEBOOK).should('exist'); }); - it('Duplicates and renames a notebook', () => { + it('Duplicates a notebook', () => { cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).click(); - cy.get('.euiButton__text').contains('Actions').click(); - cy.get('.euiContextMenuItem__text').contains('Duplicate').click(); - cy.get('.euiButton__text').contains('Duplicate').click(); + cy.get('button[data-test-subj="notebookTableActionBtn"]').click(); + cy.get('button[data-test-subj="duplicateNotebookBtn"]').click(); + cy.get('button[data-test-subj="custom-input-modal-confirm-button"]').click(); cy.get('.euiCheckbox__input[title="Select this row"]').eq(1).click(); + }); + + it('Renames a notebook', () => { cy.get('.euiCheckbox__input[title="Select this row"]').eq(0).click(); - cy.get('.euiButton__text').contains('Actions').click(); - cy.get('.euiContextMenuItem__text').contains('Rename').click(); - cy.get('input.euiFieldText').type(' (rename)'); - cy.get('.euiButton__text').contains('Rename').click(); + cy.get('button[data-test-subj="notebookTableActionBtn"]').click(); + cy.get('button[data-test-subj="renameNotebookBtn"]').click(); + cy.get('input[data-test-subj="custom-input-modal-input"]').focus().type(' (rename)'); + cy.get('button[data-test-subj="custom-input-modal-confirm-button"]').click(); }); it('Searches existing notebooks', () => { - cy.get('input.euiFieldSearch').type('this notebook should not exist'); + cy.get('input.euiFieldSearch').focus().type('this notebook should not exist'); cy.get('.euiTableCellContent__text').contains('No items found').should('exist'); cy.get('.euiFormControlLayoutClearButton').click(); - cy.get('input.euiFieldSearch').type(TEST_NOTEBOOK + ' (copy) (rename)'); + cy.get('input.euiFieldSearch') + .focus() + .type(TEST_NOTEBOOK + ' (copy) (rename)'); cy.get('a.euiLink') .contains(TEST_NOTEBOOK + ' (copy) (rename)') @@ -119,104 +124,70 @@ describe('Testing notebooks table', () => { }); it('Notebooks table columns headers and pagination', () => { - cy.get('.euiTitle.euiTitle--small').contains('Notebooks').should('exist'); + cy.get('h3[data-test-subj="notebookTableTitle"]').should('exist'); cy.get('.euiTableCellContent__text[title="Name"]').should('exist'); cy.get('.euiTableCellContent__text[title="Last updated"]').should('exist'); cy.get('.euiTableCellContent__text[title="Created"]').should('exist'); cy.get('[data-test-subj="tablePaginationPopoverButton"]').should('exist'); }); - it('"Learn more" link under Notebooks header', () => { - cy.get('.euiTitle.euiTitle--small').contains('Notebooks'); - cy.get('.euiTextColor.euiTextColor--subdued').contains(NOTEBOOK_TEXT); - cy.get('a.euiLink.euiLink--primary').contains('Learn more').click(); - cy.get(`a[href="${OPENSEARCH_URL}"]`).should('exist'); - }); - - it('Deletes notebooks', () => { - cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').click(); - cy.get('.euiButton__text').contains('Actions').click(); - cy.get('.euiContextMenuItem__text').contains('Delete').click(); - - cy.get('button.euiButton--danger').should('be.disabled'); - - cy.get('input.euiFieldText[placeholder="delete"]').type('delete'); - cy.get('button.euiButton--danger').should('not.be.disabled'); - cy.get('.euiButton__text').contains('Delete').click(); - - cy.get('.euiTextAlign').contains('No notebooks').should('exist'); - - // keep a notebook for testing - cy.get('.euiButton__text').contains('Create notebook').click(); - cy.get('input.euiFieldText').type(TEST_NOTEBOOK); - cy.get('.euiButton__text') - .contains(/^Create$/) - .click(); + it('Deletes all notebooks', () => { + cy.get('input[data-test-subj="checkboxSelectAll"]').click(); + cy.get('button[data-test-subj="notebookTableActionBtn"]').click(); + cy.get('button[data-test-subj="deleteNotebookBtn"]').click(); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').should('be.disabled'); + cy.get('input[data-test-subj="delete-notebook-modal-input"]').focus().type('delete'); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').should( + 'not.be.disabled' + ); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').click(); + moveToNotebookHome(); + cy.get('div[data-test-subj="notebookEmptyTableText"]').should('exist'); }); }); -describe('Test reporting integration if plugin installed', () => { - beforeEach(() => { - cy.visit(`${Cypress.env('opensearchDashboards')}/app/observability-notebooks#/`); - cy.get('.euiTableCellContent').contains(TEST_NOTEBOOK).click(); - cy.wait(delay); //page needs to process before checking - cy.get('body').then(($body) => { - skipOn($body.find('#reportingActionsButton').length <= 0); - }); - }); - - it('Create in-context PDF report from notebook', () => { - cy.get('#reportingActionsButton').click(); - cy.get('button.euiContextMenuItem:nth-child(1)').contains('Download PDF').click(); - cy.get('#downloadInProgressLoadingModal').should('exist'); - }); - - it('Create in-context PNG report from notebook', () => { - cy.get('#reportingActionsButton').click(); - cy.get('button.euiContextMenuItem:nth-child(2)').contains('Download PNG').click(); - cy.get('#downloadInProgressLoadingModal').should('exist'); - }); - - it('Create on-demand report definition from context menu', () => { - cy.get('#reportingActionsButton').click(); - cy.get('button.euiContextMenuItem:nth-child(3)').contains('Create report definition').click(); - cy.location('pathname', { timeout: 60000 }).should('include', '/reports-dashboards'); - cy.get('#reportSettingsName').type('Create notebook on-demand report'); - cy.get('#createNewReportDefinition').click({ force: true }); - }); - - it('View reports homepage from context menu', () => { - cy.get('#reportingActionsButton').click(); - cy.get('button.euiContextMenuItem:nth-child(4)').contains('View reports').click(); - cy.location('pathname', { timeout: 60000 }).should('include', '/reports-dashboards'); +describe('Testing paragraphs', () => { + before(() => { + moveToNotebookHome(); + cy.get('a[data-test-subj="createNotebookPrimaryBtn"]').click(); + cy.get('input[data-test-subj="custom-input-modal-input"]').focus().type(TEST_NOTEBOOK); + cy.get('button[data-test-subj="custom-input-modal-confirm-button"]').click(); + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); }); -}); -describe('Testing paragraphs', () => { beforeEach(() => { moveToTestNotebook(); }); - it('Goes into a notebook and creates paragraphs', () => { - cy.get('.euiButton__text').contains('Add').click({ force: true }); - - cy.get('.euiTextArea').should('exist'); + it('Creates a code paragraph', () => { + cy.get('button[data-test-subj="emptyNotebookAddCodeBlockBtn"]').click(); + cy.get('textarea[data-test-subj="editorArea-0"]').should('exist'); + cy.get('button[data-test-subj="runRefreshBtn-0"]').contains('Run').click(); + cy.get('div[data-test-subj="paragraphInputErrorText"]') + .contains('Input is required.') + .should('exist'); + }); - cy.get('.euiButton__text').contains('Run').click(); - cy.get('.euiTextColor').contains('Input is required.').should('exist'); - cy.get('.euiTextArea').clear(); - cy.get('.euiTextArea').type(MARKDOWN_TEXT); + it('Renders markdown', () => { + cy.get('button[data-test-subj="paragraphToggleInputBtn"]').click(); + cy.get('.euiCodeBlock').click(); + cy.get('textarea[data-test-subj="editorArea-0"]').clear(); + cy.get('textarea[data-test-subj="editorArea-0"]').focus().type(MARKDOWN_TEXT); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('button[data-test-subj="runRefreshBtn-0"]').click(); + cy.get('textarea[data-test-subj="editorArea-0"]').should('not.exist'); + cy.get(`a[href="${SAMPLE_URL}"]`).should('exist'); + cy.get('code').contains('POST').should('exist'); + cy.get('td').contains('b2').should('exist'); }); it('Has working breadcrumbs', () => { - cy.get('.euiBreadcrumb').contains(TEST_NOTEBOOK).click(); - cy.get('.euiTitle').contains(TEST_NOTEBOOK).should('exist'); - cy.get('.euiBreadcrumb').contains('Notebooks').click(); - cy.get('.euiTitle').contains('Notebooks').should('exist'); - cy.get('.euiBreadcrumb').contains('Observability').click(); - cy.get('.euiTitle').contains('Logs').should('exist'); + cy.get('a[data-test-subj="breadcrumb last"]').contains(TEST_NOTEBOOK).click(); + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); + cy.get('a[data-test-subj="breadcrumb"]').contains('Notebooks').click(); + cy.get('h3[data-test-subj="notebookTableTitle"]').should('exist'); + cy.get('a[data-test-subj="breadcrumb first"]').contains('Observability').click(); + cy.get('h1[data-test-subj="eventHomePageTitle"]').should('exist'); }); it('Paragraph actions layout', () => { @@ -229,112 +200,115 @@ describe('Testing paragraphs', () => { cy.get('.euiContextMenuItem__text').eq(4).contains('Delete all paragraphs'); }); - it('Renders markdown', () => { - cy.get('.euiTextArea').should('not.exist'); - cy.get(`a[href="${SAMPLE_URL}"]`).should('exist'); - cy.get('code').contains('POST').should('exist'); - cy.get('td').contains('b2').should('exist'); - }); - it('Shows output message', () => { - cy.get('button[aria-label="Toggle show input"]').click(); - cy.get('.euiTextColor').contains('Last successful run').should('exist'); - - cy.get('pre.input').eq(0).click(); - cy.get('.euiTextArea').type('Another text'); - - cy.get('.euiTextColor').contains('Last successful run').should('exist'); + cy.get('button[data-test-subj="paragraphToggleInputBtn"]').click(); + cy.get('div[data-test-subj="lastRunText"]').should('exist'); + cy.get('.euiCodeBlock').click(); + cy.get('textarea[data-test-subj="editorArea-0"]').focus().type('Another text'); + cy.get('div[data-test-subj="lastRunText"]').should('exist'); }); it('Renders input only mode', () => { - cy.get('.euiButton__text[title="Input only"]').click(); + cy.get('input[data-test-subj="input_only"]').should('exist'); + cy.get('input[data-test-subj="input_only"]').click({ force: true }); cy.get('div.markdown-body').should('not.exist'); - cy.get('.euiLink').contains('View both').should('exist'); - cy.get('.euiLink').contains('View both').click(); + cy.get('button[data-test-subj="viewBothLink"]').should('exist'); + cy.get('button[data-test-subj="viewBothLink"]').click(); cy.get('code').contains('POST').should('exist'); - cy.get('.euiLink').contains('View both').should('not.exist'); + cy.get('button[data-test-subj="viewBothLink"]').should('not.exist'); }); it('Renders output only mode', () => { - cy.get('.euiButton__text[title="Output only"]').click(); - + cy.get('input[data-test-subj="output_only"]').should('exist'); + cy.get('input[data-test-subj="output_only"]').click({ force: true }); cy.get('button[aria-label="Open paragraph menu"]').should('not.exist'); - cy.get('button[aria-label="Toggle show input"]').should('not.exist'); + cy.get('button[data-test-subj="paragraphToggleInputBtn"]').should('not.exist'); cy.get('code').contains('POST').should('exist'); }); it('Duplicates paragraphs', () => { cy.get('.euiButtonIcon[aria-label="Open paragraph menu"]').eq(0).click(); - cy.get('.euiContextMenuItem__text').contains('Duplicate').eq(0).click(); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('button[data-test-subj="duplicateParagraphBtn"]').click(); + cy.get('button[data-test-subj="runRefreshBtn-1"]').click(); cy.get(`a[href="${SAMPLE_URL}"]`).should('have.length.gte', 2); }); it('Adds a dashboards visualization paragraph', () => { - cy.contains('Add paragraph').click(); - cy.get('.euiContextMenuItem__text').contains('Visualization').click(); + cy.intercept('GET', '**/api/saved_objects/_find?type=observability-visualization').as( + 'getObservabilityVisualization' + ); + cy.get('button[data-test-subj="AddParagraphButton"]').click(); + cy.get('button[data-test-subj="AddVisualizationBlockBtn"]').click(); + cy.wait('@getObservabilityVisualization'); + + cy.get('button[data-test-subj="runRefreshBtn-2"]').click(); + cy.get('div[data-test-subj="paragraphInputErrorText"]') + .contains('Visualization is required.') + .should('exist'); - cy.get('.euiButton__text').contains('Run').click(); - cy.get('.euiTextColor').contains('Visualization is required.').should('exist'); - cy.wait(delay); cy.get('.euiButton__text').contains('Browse').click(); - cy.wait(delay); - cy.get('.euiFieldSearch') + cy.get('.euiModalHeader__title').contains('Browse visualizations').should('exist'); + cy.get('input[aria-label="Searchable Visualizations"]') .focus() .type('[Flights] Flight Count and Average Ticket Price{enter}'); - cy.get('.euiButton__text').contains('Select').click(); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('button[data-test-subj="para-input-select-button"]').click(); + cy.get('button[data-test-subj="runRefreshBtn-2"]').click(); cy.get('div.visualization').should('exist'); }); it('Adds a SQL query paragraph', () => { - cy.contains('Add paragraph').click(); - cy.get('.euiContextMenuItem__text').contains('Code block').click(), - { timeout: COMMAND_TIMEOUT_LONG }; - cy.wait(delay); //SQL_QUERY_TEXT will sometimes fail to type without this delay + cy.get('button[data-test-subj="AddParagraphButton"]').click(); + cy.get('button[data-test-subj="AddCodeBlockBtn"]').click(); - cy.get('.euiTextArea').type(SQL_QUERY_TEXT); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('textarea[data-test-subj="editorArea-3"]').clear(); + cy.get('textarea[data-test-subj="editorArea-3"]').focus(); + cy.get('textarea[data-test-subj="editorArea-3"]').type(SQL_QUERY_TEXT); + cy.get('button[data-test-subj="runRefreshBtn-3"]').click(); - cy.get('b').contains('select * from opensearch_dashboards_sample_data_flights limit 20'); + cy.get('textarea[data-test-subj="editorArea-3"]').should('not.exist'); + cy.get('div[data-test-subj="queryOutputText"]') + .contains('select * from opensearch_dashboards_sample_data_flights limit 20') + .should('exist'); cy.get('.euiDataGrid__overflow').should('exist'); }); it('Renders very long markdown as wrapped', () => { - cy.contains('Add paragraph').click(); - cy.get('.euiContextMenuItem__text').contains('Code block').click(), - { timeout: COMMAND_TIMEOUT_LONG }; - cy.wait(delay); //SQL_QUERY_TEXT will sometimes fail to type without this delay + cy.get('button[data-test-subj="AddParagraphButton"]').click(); + cy.get('button[data-test-subj="AddCodeBlockBtn"]').click(); const testWord = uuid4().replace(/-/gi, '').repeat(10); - cy.get('.euiTextArea').type(`%md\n${testWord}`); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('textarea[data-test-subj="editorArea-4"]').clear(); + cy.get('textarea[data-test-subj="editorArea-4"]').focus(); + cy.get('textarea[data-test-subj="editorArea-4"]').type(`%md\n${testWord}`); + cy.get('button[data-test-subj="runRefreshBtn-4"]').click(); - cy.get('p') + cy.get('textarea[data-test-subj="editorArea-4"]').should('not.exist'); + cy.get('div[data-test-subj="markdownOutputText"]') .contains(testWord) .then((element) => { const clientWidth = element[0].clientWidth; const scrollWidth = element[0].scrollWidth; - console.log('paragraph', { clientWidth, scrollWidth }); expect(scrollWidth, 'Output Text has not been wrapped').to.be.at.most(clientWidth); }); }); it('Renders very long query as wrapped', () => { - cy.contains('Add paragraph').click(); - cy.get('.euiContextMenuItem__text').contains('Code block').click(), - { timeout: COMMAND_TIMEOUT_LONG }; - cy.wait(delay); //SQL_QUERY_TEXT will sometimes fail to type without this delay - - const testWord = uuid4().replace(/-/gi, '').repeat(10); - cy.get('.euiTextArea').type(`%sql\nSELECT 1 AS ${testWord}`); - cy.get('.euiButton__text').contains('Run').click(); - - cy.get('b') + cy.get('button[data-test-subj="AddParagraphButton"]').click(); + cy.get('button[data-test-subj="AddCodeBlockBtn"]').click(); + + const testWord = 'randomText' + uuid4().replace(/-/gi, '').repeat(10); + cy.get('textarea[data-test-subj="editorArea-5"]').clear(); + cy.get('textarea[data-test-subj="editorArea-5"]').focus(); + cy.get('textarea[data-test-subj="editorArea-5"]').type(`%sql\nSELECT 1 AS ${testWord}`); + cy.get('button[data-test-subj="runRefreshBtn-5"]').click(); + + cy.get('textarea[data-test-subj="editorArea-5"]').should('not.exist'); + cy.get('div[data-test-subj="queryOutputText"]').contains(testWord).should('exist'); + cy.get('div[data-test-subj="queryOutputText"]') .contains(testWord) .then((element) => { const clientWidth = element[0].clientWidth; @@ -344,59 +318,70 @@ describe('Testing paragraphs', () => { }); it('Adds an observability visualization paragraph', () => { - cy.contains('Add paragraph').click(); - cy.get('.euiContextMenuItem__text').contains('Visualization').click(); - - cy.get('.euiButton__text').contains('Run').click(); - cy.get('.euiTextColor').contains('Visualization is required.').should('exist'); - - cy.wait(delay); - cy.get('.euiButton__text').contains('Browse').click({ force: true }); - cy.wait(delay); - cy.get('.euiFieldSearch').focus().type('[Logs] Count total requests by tags{enter}'); - cy.get('.euiButton__text').contains('Select').click(); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('button[data-test-subj="AddParagraphButton"]').click(); + cy.get('button[data-test-subj="AddVisualizationBlockBtn"]').click(); + + cy.get('button[data-test-subj="runRefreshBtn-6"]').click(); + cy.get('div[data-test-subj="paragraphInputErrorText"]') + .contains('Visualization is required.') + .should('exist'); + cy.get('div[data-test-subj="comboBoxInput"]').click(); + cy.get('input[data-test-subj="comboBoxSearchInput"]') + .focus() + .type('[Logs] Count total requests by tags'); + + cy.get('.euiComboBoxOption__content').contains('[Logs] Count total requests by tags').click(); + cy.get('button[data-test-subj="runRefreshBtn-6"]').click(); cy.get('h5').contains('[Logs] Count total requests by tags').should('exist'); }); it('Adds a PPL query paragraph', () => { - cy.contains('Add paragraph').click(); - cy.get('.euiContextMenuItem__text').contains('Code block').click(), - { timeout: COMMAND_TIMEOUT_LONG }; - cy.wait(delay); //PPL_QUERY_TEXT will sometimes fail to type without this delay + cy.get('button[data-test-subj="AddParagraphButton"]').click(); + cy.get('button[data-test-subj="AddCodeBlockBtn"]').click(); - cy.get('.euiTextArea').type(PPL_QUERY_TEXT); - cy.get('.euiButton__text').contains('Run').click(); + cy.get('textarea[data-test-subj="editorArea-7"]').clear(); + cy.get('textarea[data-test-subj="editorArea-7"]').focus(); + cy.get('textarea[data-test-subj="editorArea-7"]').type(PPL_QUERY_TEXT); + cy.get('button[data-test-subj="runRefreshBtn-7"]').click(); - cy.get('b').contains('source=opensearch_dashboards_sample_data_flights'); + cy.get('textarea[data-test-subj="editorArea-7"]').should('not.exist'); + cy.get('div[data-test-subj="queryOutputText"]') + .contains('source=opensearch_dashboards_sample_data_flights') + .should('exist'); cy.get('.euiDataGrid__overflow').should('exist'); }); it('Clears outputs', () => { - cy.wait(delay); // need to wait for paragraphs to load first + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); + cy.get('[data-test-subj="notebook-paragraph-actions-button"]').should('exist'); cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Clear all outputs').click(); - cy.get('.euiButton__text').contains('Clear').click(); + cy.get('button[data-test-subj="confirmModalConfirmButton"]').click(); cy.get(`a[href="${SAMPLE_URL}"]`).should('not.exist'); }); it('Runs all paragraphs', () => { - cy.wait(delay); // need to wait for paragraphs to load first + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Run all paragraphs').click(); cy.get(`a[href="${SAMPLE_URL}"]`).should('exist'); }); - it('Adds paragraph to top and bottom', () => { - cy.wait(delay); // need to wait for paragraphs to load first - cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click(); + it('Adds paragraph to top', () => { + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); + cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Add paragraph to top').click(); cy.get('.euiContextMenuItem__text').contains('Code block').click(); - cy.wait(delay); + + cy.get('.euiText').contains('[1] Code block').should('exist'); + }); + + it('Adds paragraph to bottom', () => { + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Add paragraph to bottom').click(); cy.get('.euiContextMenuItem__text').contains('Code block').click(); @@ -406,6 +391,7 @@ describe('Testing paragraphs', () => { }); it('Moves paragraphs', () => { + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); cy.get('.euiButtonIcon[aria-label="Open paragraph menu"').eq(0).click(); cy.get('.euiContextMenuItem-isDisabled').should('have.length.gte', 2); cy.get('.euiContextMenuItem__text').contains('Move to bottom').click(); @@ -414,17 +400,16 @@ describe('Testing paragraphs', () => { }); it('Duplicates and renames the notebook', () => { - cy.wait(delay); + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); cy.get('[data-test-subj="notebook-notebook-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Duplicate notebook').click(); cy.get('.euiButton__text').contains('Duplicate').click(); cy.get('[data-test-subj="notebook-notebook-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Rename notebook').click(); - cy.get('input.euiFieldText[data-autofocus="true"]').type(' (rename)'); + cy.get('input.euiFieldText[data-autofocus="true"]').focus().type(' (rename)'); cy.get('.euiButton__text').last().contains('Rename').click(); cy.reload(); - cy.wait(delay); cy.get('.euiTitle') .contains(TEST_NOTEBOOK + ' (rename)') @@ -433,41 +418,44 @@ describe('Testing paragraphs', () => { }); it('Deletes paragraphs', () => { + cy.get('h1[data-test-subj="notebookTitle"]').contains(TEST_NOTEBOOK).should('exist'); cy.get('[data-test-subj="notebook-paragraph-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Delete all paragraphs').click(); - cy.get('.euiButton__text').contains('Delete').click(); + cy.get('button[data-test-subj="confirmModalConfirmButton"]').click(); - cy.get('.euiTextAlign').contains('No paragraphs').should('exist'); + cy.get('button[data-test-subj="emptyNotebookAddCodeBlockBtn"]').should('exist'); }); it('Deletes notebook', () => { cy.get('[data-test-subj="notebook-notebook-actions-button"]').click(); cy.get('.euiContextMenuItem__text').contains('Delete notebook').click(); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').should('be.disabled'); - cy.get('button.euiButton--danger').should('be.disabled'); - - cy.get('input.euiFieldText[placeholder="delete"]').type('delete'); - cy.get('button.euiButton--danger').should('not.be.disabled'); - cy.get('.euiButton__text').contains('Delete').click(); - - cy.get('.euiButton__text').contains('Create notebook').should('exist'); + cy.get('input[data-test-subj="delete-notebook-modal-input"]').focus().type('delete'); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').should( + 'not.be.disabled' + ); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').click(); + cy.get('a[data-test-subj="createNotebookPrimaryBtn"]').should('exist'); }); +}); +describe('clean up all test data', () => { it('Cleans up test notebooks', () => { - cy.get('[data-test-subj="notebook-notebook-actions-button"]').click(); - cy.get('.euiContextMenuItem__text').contains('Delete notebook').click(); - - cy.get('button.euiButton--danger').should('be.disabled'); - - cy.get('input.euiFieldText[placeholder="delete"]').type('delete'); - cy.get('button.euiButton--danger').should('not.be.disabled'); - cy.get('.euiButton__text').contains('Delete').click(); - - cy.get('.euiText').contains('No notebooks').should('exist'); + moveToNotebookHome(); + cy.get('input[data-test-subj="checkboxSelectAll"]').click(); + cy.get('button[data-test-subj="notebookTableActionBtn"]').click(); + cy.get('button[data-test-subj="deleteNotebookBtn"]').click(); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').should('be.disabled'); + cy.get('input[data-test-subj="delete-notebook-modal-input"]').focus().type('delete'); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').should( + 'not.be.disabled' + ); + cy.get('button[data-test-subj="delete-notebook-modal-delete-button"]').click(); + moveToNotebookHome(); + cy.get('div[data-test-subj="notebookEmptyTableText"]').should('exist'); }); -}); -describe('clean up all test data', () => { it('Delete visualizations from event analytics', () => { moveToEventsHome(); cy.get('[data-test-subj="tablePaginationPopoverButton"]').trigger('mouseover').click(); @@ -481,7 +469,6 @@ describe('clean up all test data', () => { cy.get('.euiButton__text').contains('Delete').trigger('mouseover').click(); cy.get('.euiTextAlign').contains('No Queries or Visualizations').should('exist'); }); - it('Deletes test panel', () => { moveToPanelHome(); cy.get('.euiCheckbox__input[data-test-subj="checkboxSelectAll"]').trigger('mouseover').click(); @@ -493,3 +480,13 @@ describe('clean up all test data', () => { cy.get('.euiButton__text').contains('Delete').trigger('mouseover').click(); }); }); + +describe('link check ', () => { + it('"Learn more" link under Notebooks header', () => { + moveToNotebookHome(); + cy.get('h3[data-test-subj="notebookTableTitle"]').should('exist'); + cy.get('div[data-test-subj="notebookTableDescription"]').contains(NOTEBOOK_TEXT); + cy.get('a.euiLink.euiLink--primary').contains('Learn more').click(); + cy.get(`a[href="${OPENSEARCH_URL}"]`).should('exist'); + }); +}); diff --git a/.cypress/utils/constants.js b/.cypress/utils/constants.js index 706061baff..2f6150d308 100644 --- a/.cypress/utils/constants.js +++ b/.cypress/utils/constants.js @@ -3,9 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -export const delay = 1500; -export const COMMAND_TIMEOUT_LONG = 10000; - //BASE Constants export const BACKEND_BASE_PATH = Cypress.env('opensearch'); export const FONTEND_BASE_PATH = Cypress.env('opensearchDashboards'); @@ -14,7 +11,7 @@ export const FONTEND_BASE_PATH = Cypress.env('opensearchDashboards'); export const DATASOURCES_API_PREFIX = '/app/datasources'; export const DATASOURCES_PATH = { DATASOURCES_CREATION_BASE: `${DATASOURCES_API_PREFIX}#/new`, - DATASOURCES_CONFIG_BASE: `${DATASOURCES_API_PREFIX}#/configure` + DATASOURCES_CONFIG_BASE: `${DATASOURCES_API_PREFIX}#/configure`, }; // trace analytics @@ -26,34 +23,44 @@ export const AUTH_SERVICE_SPAN_ID = '277a5934acf55dcf'; export const testDataSet = [ { - mapping_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-service-map-mappings.json', - data_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-service-map.json', + mapping_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-service-map-mappings.json', + data_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-service-map.json', index: 'otel-v1-apm-service-map', }, { - mapping_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000001-mappings.json', - data_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000001.json', + mapping_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000001-mappings.json', + data_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000001.json', index: 'otel-v1-apm-span-000001', }, { - mapping_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000001-mappings.json', - data_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000002.json', + mapping_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000001-mappings.json', + data_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/otel-v1-apm-span-000002.json', index: 'otel-v1-apm-span-000002', }, -] +]; export const jaegerTestDataSet = [ { - mapping_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-service-2023-01-24-mappings.json', - data_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-service-2023-01-24.json', + mapping_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-service-2023-01-24-mappings.json', + data_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-service-2023-01-24.json', index: 'jaeger-service-2023-01-24', }, { - mapping_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-span-2023-01-24-mappings.json', - data_url: 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-span-2023-01-24.json', + mapping_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-span-2023-01-24-mappings.json', + data_url: + 'https://raw.githubusercontent.com/opensearch-project/dashboards-observability/main/.cypress/utils/jaeger-span-2023-01-24.json', index: 'jaeger-span-2023-01-24', }, -] +]; export const setTimeFilter = (setEndTime = false, refresh = true) => { const startTime = 'Mar 25, 2021 @ 10:00:00.000'; @@ -78,7 +85,7 @@ export const setTimeFilter = (setEndTime = false, refresh = true) => { .type('{selectall}' + endTime, { force: true }); } if (refresh) cy.get('.euiButton__text').contains('Refresh').click(); - cy.get('.euiTableRow').should('have.length.greaterThan', 3);//Replaces Wait + cy.get('.euiTableRow').should('have.length.greaterThan', 3); //Replaces Wait }; // notebooks @@ -86,7 +93,8 @@ export const TEST_NOTEBOOK = 'Test Notebook'; export const TEST_INTEGRATION_INSTANCE = 'nginx-test'; export const TEST_SAMPLE_INSTANCE = 'nginx-sample'; export const SAMPLE_URL = 'https://github.com/opensearch-project/sql/tree/main/sql-jdbc'; -export const NOTEBOOK_TEXT = 'Use Notebooks to interactively and collaboratively develop rich reports backed by live data. Common use cases for notebooks includes creating postmortem reports, designing run books, building live infrastructure reports, or even documentation.'; +export const NOTEBOOK_TEXT = + 'Use Notebooks to interactively and collaboratively develop rich reports backed by live data. Common use cases for notebooks includes creating postmortem reports, designing run books, building live infrastructure reports, or even documentation.'; export const OPENSEARCH_URL = 'https://opensearch.org/docs/latest/observability-plugin/notebooks/'; export const MARKDOWN_TEXT = `%md # Heading 1 @@ -112,15 +120,15 @@ POST _plugins/_sql/_explain |----|----|----|----| | a2 | b2 | c2 | d2 | | a3 | b3 | c3 | d3 | -` +`; -export const SQL_QUERY_TEXT = `%sql -select * from opensearch_dashboards_sample_data_flights limit 20 -` +export const SQL_QUERY_TEXT = `%sql +select * from opensearch_dashboards_sample_data_flights limit 20 {enter} +`; export const PPL_QUERY_TEXT = `%ppl -source=opensearch_dashboards_sample_data_flights -` +source=opensearch_dashboards_sample_data_flights {enter} +`; export const suppressResizeObserverIssue = () => { // exception is thrown on loading EuiDataGrid in cypress only, ignore for now @@ -137,28 +145,28 @@ export const verify_traces_spans_data_grid_cols_exists = () => { cy.get('.euiDataGridHeaderCell__content').contains('Start time').should('exist'); cy.get('.euiDataGridHeaderCell__content').contains('End time').should('exist'); cy.get('.euiDataGridHeaderCell__content').contains('Errors').should('exist'); -} +}; export const count_table_row = (expected_row_count) => { - cy.get('.euiDataGridHeader [role="columnheader"]').then($el => { + cy.get('.euiDataGridHeader [role="columnheader"]').then(($el) => { let colmun_header_count = Cypress.$($el).length; let table_grid_cell_count = Cypress.$('[data-test-subj="dataGridRowCell"]').length; const total_row_count = table_grid_cell_count / colmun_header_count; - expect(total_row_count).to.equal(expected_row_count) + expect(total_row_count).to.equal(expected_row_count); }); -} +}; Cypress.on('uncaught:exception', (err, runnable, promise) => { // when the exception originated from an unhandled promise // rejection, the promise is provided as a third argument // you can turn off failing the test in this case if (promise) { - return false + return false; } // we still want to ensure there are no other unexpected // errors, so we let them fail the test -}) +}); Cypress.on('uncaught:exception', (err, runnable) => { if (err.message.includes('ResizeObserver loop')) return false; -}) \ No newline at end of file +}); diff --git a/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap b/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap index a180c49998..ba620dd302 100644 --- a/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap +++ b/public/components/notebooks/components/__tests__/__snapshots__/note_table.test.tsx.snap @@ -36,6 +36,7 @@ exports[` spec renders the component 1`] = ` >

Notebooks spec renders the component 1`] = ` />
spec renders the component 1`] = ` >