From 44a999ee44aab8a1f385d31fb5b59d294ff09f95 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Tue, 18 Jun 2024 13:09:20 -0700 Subject: [PATCH 01/12] most of misc-facet spec migrated. 3 more describe blocks to finish --- src/components/recordset/recordset.tsx | 2 +- src/custom.d.ts | 1 + test/e2e/locators/recordset.ts | 35 +- .../recordset/facet-presentation.spec.ts | 2 +- .../recordset/histogram-facet.spec.ts | 2 +- .../recordset/ind-facet.config.ts | 8 +- .../recordset/misc-facet.spec.ts | 873 ++++++++++++++++++ test/e2e/utils/chaise.page.js | 4 +- test/e2e/utils/recordset-utils.ts | 31 + 9 files changed, 948 insertions(+), 10 deletions(-) create mode 100644 test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts diff --git a/src/components/recordset/recordset.tsx b/src/components/recordset/recordset.tsx index 6944f9030..bed196028 100644 --- a/src/components/recordset/recordset.tsx +++ b/src/components/recordset/recordset.tsx @@ -791,7 +791,7 @@ const RecordsetInner = ({
{hasSpinner &&
- +
}
diff --git a/src/custom.d.ts b/src/custom.d.ts index 887ed7e60..1fa4b5dde 100644 --- a/src/custom.d.ts +++ b/src/custom.d.ts @@ -2,6 +2,7 @@ declare module '*.jpg'; declare module '*.png'; declare module '*.jpeg'; declare module '*.gif'; +declare module 'chance'; declare module 'plotly.js-basic-dist-min'; declare module 'react-plotly.js/factory'; declare module 'spark-md5'; diff --git a/test/e2e/locators/recordset.ts b/test/e2e/locators/recordset.ts index b048a377a..c1464d9f3 100644 --- a/test/e2e/locators/recordset.ts +++ b/test/e2e/locators/recordset.ts @@ -40,7 +40,7 @@ export default class RecordsetLocators { static async waitForRecordsetPageReady(container: Page | Locator, timeout?: number): Promise { await RecordsetLocators.getRecordSetTable(container).waitFor({ state: 'visible', timeout }); - await container.locator('.recordest-main-spinner').waitFor({ state: 'detached', timeout }); + await container.locator('.recordset-main-spinner').waitFor({ state: 'detached', timeout }); } @@ -155,6 +155,19 @@ export default class RecordsetLocators { return container.locator('tr.disabled-row'); } + static getColumnNames(container: Page | Locator): Locator { + return container.locator('.table-column-displayname > span'); +}; + + static getFirstColumn(container: Page | Locator): Locator { + return container.locator('.chaise-table-row td:nth-child(2)'); + } + + /* sort selectors */ + static getColumnSortButton(container: Page | Locator, rawColumnName: string): Locator { + return container.locator(`.c_${rawColumnName} .not-sorted-icon`); + }; + // -------------------- row-level selectors ------------------------ // @@ -174,6 +187,10 @@ export default class RecordsetLocators { return container.locator('.recordset-table').locator('.chaise-checkbox input.checked'); } + static getClearSelectedRows(container: Page | Locator): Locator { + return container.locator('.clear-all-btn'); + } + static getRowFirstCell(container: Page | Locator, rowIndex: number, isDisabled?: boolean): Locator { const rows = isDisabled ? RecordsetLocators.getRows(container) : RecordsetLocators.getDisabledRows(container) return rows.nth(rowIndex).locator('td:not(.action-btns)').first(); @@ -206,6 +223,14 @@ export default class RecordsetLocators { return container.locator('.side-panel-resizable'); } + static getHideFilterPanelBtn(container: Page | Locator): Locator { + return container.locator('.hide-filter-panel-btn'); + } + + static getShowFilterPanelBtn(container: Page | Locator): Locator { + return container.locator('.show-filter-panel-btn'); +} + static getAllFacets(container: Page | Locator): Locator { return container.locator('.panel-group .facet-panel'); } @@ -255,6 +280,14 @@ export default class RecordsetLocators { return facet.locator('.chaise-checkbox input.checked'); } + static getDisabledFacetOptions(facet: Locator): Locator { + return facet.locator('.chaise-checkbox input[disabled]'); + } + + static getFacetMoreFiltersText(facet: Locator): Locator { + return facet.locator('.more-filters'); + } + static getFacetOption(facet: Locator, optionIdx: number): Locator { return facet.locator(`.checkbox-${optionIdx}`); } diff --git a/test/e2e/specs/delete-prohibited/recordset/facet-presentation.spec.ts b/test/e2e/specs/delete-prohibited/recordset/facet-presentation.spec.ts index d307bfd92..6663fdb07 100644 --- a/test/e2e/specs/delete-prohibited/recordset/facet-presentation.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/facet-presentation.spec.ts @@ -173,7 +173,7 @@ test('Viewing Recordset with Faceting, default presentation based on facets anno const mainSearch = RecordsetLocators.getMainSearchInput(page); await RecordsetLocators.getClearAllFilters(page).click(); - await page.locator('.recordest-main-spinner').waitFor({ state: 'detached' }); + await page.locator('.recordset-main-spinner').waitFor({ state: 'detached' }); await mainSearch.fill(testParams.searchBox.term); await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.searchBox.numRows); diff --git a/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts index 830f10585..f6011a876 100644 --- a/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts @@ -1,4 +1,4 @@ -import { test, expect, Locator } from '@playwright/test'; +import { test, expect } from '@playwright/test'; // locators import RecordsetLocators, { TimestampDateTime } from '@isrd-isi-edu/chaise/test/e2e/locators/recordset'; diff --git a/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts b/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts index 7695653eb..b03760225 100644 --- a/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts +++ b/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts @@ -5,9 +5,9 @@ export default getConfig({ configFileName: 'recordset/ind-facet.dev.json', mainSpecName: 'delete-prohibited', testMatch: [ - 'facet-presentation.spec.ts', - 'ind-facet.spec.ts', - 'four-facet-selections.spec.ts', - // 'misc-facet.spec.ts' + // 'facet-presentation.spec.ts', + // 'ind-facet.spec.ts', + // 'four-facet-selections.spec.ts', + 'misc-facet.spec.ts' ] }); diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts new file mode 100644 index 000000000..19f202941 --- /dev/null +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -0,0 +1,873 @@ +import { Locator, test, expect } from '@playwright/test'; +import chance from 'chance'; + +// locators +import AlertLocators from '@isrd-isi-edu/chaise/test/e2e/locators/alert'; +import ModalLocators from '@isrd-isi-edu/chaise/test/e2e/locators/modal'; +import RecordsetLocators from '@isrd-isi-edu/chaise/test/e2e/locators/recordset'; + +// utils +import { getCatalogID } from '@isrd-isi-edu/chaise/test/e2e/utils/catalog-utils'; +import { openFacetAndTestFilterOptions, testFacetOptions } from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; + +const testParams = { + schema_name: 'faceting', + table_name: 'main', + filter_secondary_key: { + facetIdx: 14, + option: 0, + selectedModalOption: 0, + newModalOption: 2, + totalNumOptions: 10, + numRows: 10, + numRowsAfterModal: 11, + removingOptionsNumRowsAfterModal: 25 + }, + facet_order: [ + { + title: 'facet with order and column_order false for scalar', + facetIdx: 20, + modalOptions: ['01', '02', '03', '04', '05', '06', '07'], + sortable: false, + modalOptionsSortedByScalar: [], // for type errors + hideNumOccurrences: false, + modalOptionsSortedByNumOfOccurences: ['07', '06', '05', '04', '03', '02', '01'], + columnName: 'col_w_column_order_false' + }, + { + title: 'facet without order and hide_num_occurrences true', + facetIdx: 21, + modalOptions: ['01', '13', '12', '11', '10', '09', '08', '07', '06', '05', '04', '03', '02'], + sortable: true, + modalOptionsSortedByScalar: ['13', '12', '11', '10', '09', '08', '07', '06', '05', '04', '03', '02', '01'], + hideNumOccurrences: true, + modalOptionsSortedByNumOfOccurences: [], + columnName: 'col_w_column_order' + } + ], + not_null: { + facetIdx: 5, + result_num_w_not_null: 25, + modal_available_options: 10, + disabled_rows_w_not_null: 11, + options_w_not_null: [ + 'All records with value', 'No value', 'one', 'Empty', 'two', 'seven', 'eight', 'elevens', 'four', 'six', 'ten', 'three' + ] + }, + null_filter: { + panel: { + facetIdx: 5, + totalNumOptions: 12, + option: 1, + numRows: 5 + }, + right_join: { + firstFacet: { + name: 'F3 Entity', + idx: 16, + totalNumOptions: 4, + option: 1, + numRows: 23 + }, + secondFacet: { + name: 'F5', + idx: 17, + options: ['All records with value', 'one'] + } + } + }, + hide_row_count: { + hidden: { + facetIdx: 11, + displayingText: 'Displaying all13records', + numModalOptions: 13 + + }, + shown: { + facetIdx: 10, + displayingText: 'Displaying all12of 12 records', + numModalOptions: 12 + } + }, + customFilter: { + ermrestFilter: 'id=1;id=2;int_col::geq::20', + ermrestFilterDisplayed: 'id=1; id=2; int_col::geq::20', + numRows: 7, + numRowsWFacet: 1, + numRowsWOFilter: 1, + facet: 0, + totalNumOptions: 7, + options: ['1', '2', '6', '7', '8', '9', '10'], + optionsWOFilter: ['2', '1', '3', '4', '5', '6', '7', '8', '9', '10'], + option: 1 + }, + customFacet: { + cfacet: { 'displayname': 'Custom Facet Query', 'ermrest_path': 'id=1;id=2;id=3;id=14;id=15;id=16;id=17;id=18' }, + cfacetBlob: 'N4IgJglgzgDgNgQwJ4DsEFsCmIBcIDCArlAC4D26ABAGIIDGmJlAioZgE5IgA0IH67TKQD6MBCQAWuEBDABeAIwBuWXIBMK+QGZNigCy6FAVkMA2QwHZDADhABfIA', + facet: 10, + totalNumOptions: 3, + option: 1, + numRows: 8, + numRowsWFacet: 3, + numRowsWOCustomFacet: 10, + options: ['No value', 'one', 'two'], + optionsWOCustomFacet: ['No value', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'] + }, + maximumLength: { + facetIdx: 22, + numRows: 25, + filteredNumRows: 24, + secondFacetIdx: 6, + secondFacetOption: 7, + secondFacetNumOptions: 10, + option: 1 + }, + recordColumns: [ + 'text_col', 'longtext_col', 'markdown_col', 'int_col', 'float_col', 'date_col', 'timestamp_col', + 'boolean_col', 'jsonb_col', '1-o7Ye2EkulrWcCVFNHi3A', 'hmZyP_Ufo3E5v_nmdTXyyA' + ], + recordValues: { + text_col: 'one', + // eslint-disable-next-line max-len + longtext_col: 'lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod.', + markdown_col: 'one', + int_col: '11', + float_col: '11.1100', + date_col: '2001-01-01', + timestamp_col: '2001-01-01 00:01:01', + boolean_col: 'true', + jsonb_col: JSON.stringify({ 'key': 'one' }, undefined, 2), + '1-o7Ye2EkulrWcCVFNHi3A': 'one', // faceting_main_fk1 + 'hmZyP_Ufo3E5v_nmdTXyyA': 'one' // faceting_main_fk2 + }, + shared_path_prefix: { + facetObject: { + 'and': [ + { 'sourcekey': 'outbound_to_f1', 'choices': [1, 2, 3, 4, 5, 6] }, + { 'sourcekey': 'outbound_to_f1_to_outbound1', 'choices': [3, 4] } + ] + }, + facetBlob: [ + 'N4IghgdgJiBcDaoDOB7ArgJwMYFMDWOAnnCOgC4BG60A+mSjQGYCMIANCFgBYoCWuSOPGZsATGwDMbACxsArGwBsAXQC+bZOmz4iJclTS16TZnQb7qUVh258BQqdLVqgA' + ].join(''), + numRows: 2, + firstFacet: { + index: 10, + options: ['No value', 'one', 'two', 'three', 'four', 'five', 'six'], + modalOptions: ['three', 'four'] + }, + secondFacet: { + index: 19, + options: ['three (o1)', 'four (o1)', 'one (o1)', 'six (o1)'], + modalOptions: ['1', '3', '4', '6'] + } + }, + unsupported_filters_error: { + facetObject: { + 'and': [ + // will be ignored because of invalid sourcekey name + { + 'sourcekey': 'some_invalid_key', + 'markdown_name': 'Facet 1', + 'choices': ['1', '2'] + }, + // will be ignored because it's ending in f4 table not f5: + { + 'sourcekey': 'path_to_f4_scalar_w_id', + 'markdown_name': 'from_name', + 'source_domain': { + 'schema': 'faceting', + 'table': 'f5' + }, + 'choices': ['3', '4'] + }, + // partially will be ignored + { + 'sourcekey': 'outbound_to_f1', + 'markdown_name': 'F1', + 'source_domain': { + 'schema': 'faceting', + 'table': 'f1', + 'column': 'term' + }, + 'choices': ['one', 'missing data', 'two', 'three', 'four', 'more missing data'] + } + ] + }, + facetBlob: [ + 'N4IghgdgJiBcDaoDOB7ArgJwMYFMDWOAnnCKgLY4D6AlhAG5gA21UlBxANCGWBnlCgDuEShDAUSAMTC4ALg', + 'AIAjCC5YAFimq4kceCGVcATCAC6AXw7J02fERIAHMLLWVZKSgDMALJSRYmvJSCNDBcPHwCwqLiOCQeGChk0', + 'RJcqJi4lAI8tHDI6jg8cTI4srQA5iogsmAARoyxsCAeAKwgFiDqmtq6IADMlV6mFlbptsSN6LI16NCu7h4G', + '3Lz8QiJiEo2Si2k2mYlgObB5agVgRXLlldV1DU2LWCiMaGQQJLI4GGRtqhpaODoIEAoCCxMLUJBIcryKBOM', + '5cWSCFBXNQYHCgprWSpkFCo+RkcGQiBlaGwobmIA' + ].join(''), + errorTitle: 'Unsupported Filters', + errorMessage: [ + 'Some (or all) externally supplied filter criteria cannot be implemented with the current catalog content. ', + 'This may be due to lack of permissions or changes made to the content since the criteria were initially saved. ', + 'Discarded facets: Facet 1, from_name ', + 'Facets with some discarded choices: F1', + 'Click OK to continue with the subset of filter criteria which are supported at this time.', + 'Show Error Details' + ].join(''), + errorDetails: [ + 'Discarded facets:\n\n- Facet 1 (2 choices):\n - 1\n - 2\n- from_name (2 choices):\n - 3\n - 4\n\n\n', + 'Partially discarded facets:\n\n- F1 (2/6 choices):\n - missing data\n - more missing data' + ].join(''), + facetBlobAfterOK: [ + 'N4IghgdgJiBcDaoDOB7ArgJwMYFM6JHQBcAjdafEAMzFyIEsIBzEAGhAFsxGB9KgawCMIALoBfdvRgj2WABYp6uJPgAsrQawDMrAEzjxQA' + ].join(''), + numRows: 22 + }, + hide_selected_items: { + // not used and only added here so we know what the blob represents + facetObject: { + 'and': [ + { 'source': 'id', 'choices': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] }, + { 'source': 'text_col', 'choices': ['one', 'two'] } + ] + }, + // eslint-disable-next-line max-len + facetBlob: 'N4IghgdgJiBcDaoDOB7ArgJwMYFM4gEsYAaELACxQNyTngEZiAmYgZmIBZiBWYgNmIB2YgA5iATmL0ADFMb0mAXQC+xZOmx5YIAC44AHjoD6WFABsQpClRp0QKCHlI6A7ihAqVQA', + numRows: 10, + firstFacet: { + index: 0, + options: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], + optionsAfterFirstChange: ['2', '3', '4', '5', '6', '7', '8', '9', '10', '11'], + optionsAfterFinalChange: ['4', '5', '6', '7', '8', '9', '10', '11', '12', '1'], + }, + secondFacet: { + index: 5, + selectedOption: 2, + options: ['All records with value', 'No value', 'one', 'two', 'four', 'three'] + } + }, + hideFilterPanelClass: 'chaise-sidebar-close', + showFilterPanelClass: 'chaise-sidebar-open', + foreignKeyPopupFacetFilter: 'term\neight', + associationRTName: 'main_f3_assoc', + associationPopupFacetFilter: 'term\nfive', + associationPopupSelectedRowsFilter: 'five' +}; + +test.describe('Other facet features', () => { + test.describe.configure({ mode: 'parallel' }); + + test('selecting entity facet that is not on the shortest key.', async ({ page, baseURL }, testInfo) => { + const facet = RecordsetLocators.getFacetById(page, testParams.filter_secondary_key.facetIdx); + const modal = ModalLocators.getRecordsetSearchPopup(page); + + await test.step('should load recordset page and clear all filters', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + await test.step('Side panel should hide/show by clicking pull button', async () => { + const recPan = RecordsetLocators.getSidePanel(page), + showPanelBtn = RecordsetLocators.getShowFilterPanelBtn(page), + hidePanelBtn = RecordsetLocators.getHideFilterPanelBtn(page); + + await expect.soft(hidePanelBtn).toBeVisible(); + // regular expression to test "contains" + await expect.soft(recPan).toHaveAttribute('class', /open-panel/); + + await hidePanelBtn.click(); + await expect.soft(showPanelBtn).toBeVisible(); + // regular expression to test "contains" + await expect.soft(recPan).toHaveAttribute('class', /close-panel/); + + await showPanelBtn.click(); + }); + + await test.step('should open the facet, select a value to filter on.', async () => { + await RecordsetLocators.getFacetHeaderButtonById(facet, testParams.filter_secondary_key.facetIdx).click(); + + // wait for facet to open + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(testParams.filter_secondary_key.totalNumOptions); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); + + await RecordsetLocators.getFacetOption(facet, testParams.filter_secondary_key.option).click(); + + // wait for request to return + await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.filter_secondary_key.numRows); + }); + + await test.step('the selected value should be selected on the modal.', async () => { + await RecordsetLocators.getShowMore(facet).click(); + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(12); + + await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(1); + await expect.soft(RecordsetLocators.getCheckboxInputs(modal).nth(testParams.filter_secondary_key.selectedModalOption)).toBeChecked(); + }); + + await test.step('selecting new values on the modal and submitting them, should change the filters on submit.', async () => { + await RecordsetLocators.getCheckboxInputs(modal).nth(testParams.filter_secondary_key.newModalOption).check(); + + const submit = ModalLocators.getSubmitButton(modal); + await expect.soft(submit).toHaveText('Submit'); + await submit.click(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.filter_secondary_key.numRowsAfterModal); + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(2); + }); + + await test.step('removing values in the modal should allow for submitting to remove the set of selected options for that facet.', async () => { + await RecordsetLocators.getShowMore(facet).click(); + await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(2); + + // clear selections in modal to remove selections in facet + await RecordsetLocators.getClearSelectedRows(modal).click(); + await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(0); + + await ModalLocators.getSubmitButton(modal).click(); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.filter_secondary_key.removingOptionsNumRowsAfterModal); + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0); + }); + }); + + test('facet modal rows and columns', async ({ page, baseURL }, testInfo) => { + await test.step('should load recordset page and clear all filters', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + for (const params of testParams.facet_order) { + const facet = RecordsetLocators.getFacetById(page, params.facetIdx); + const modal = ModalLocators.getRecordsetSearchPopup(page); + + await test.step('the rows in the modal should honor the given order.', async () => { + await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); + + // wait for facet to open + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + + // click on show more + await RecordsetLocators.getShowMore(facet).click(); + const columnValues = RecordsetLocators.getFirstColumn(modal); + await expect.soft(columnValues).toHaveCount(params.modalOptions.length); + + await expect.soft(columnValues).toHaveText(params.modalOptions); + }); + + if (!params.sortable) { + await test.step('the facet column sort option should not be available.', async () => { + await expect(RecordsetLocators.getColumnSortButton(modal, '0')).not.toBeAttached(); + }); + } else { + await test.step('users should be able to change the sort to be based on the scalar column.', async () => { + const sortBtn = RecordsetLocators.getColumnSortButton(modal, '0'); + await expect.soft(sortBtn).toBeVisible(); + + await sortBtn.click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + const columnValues = RecordsetLocators.getFirstColumn(modal); + await expect.soft(columnValues).toHaveText(params.modalOptionsSortedByScalar); + }); + } + + await test.step(`number of Occurrences column should be ${params.hideNumOccurrences ? 'hidden' : 'available'}.`, async () => { + const columns = RecordsetLocators.getColumnNames(modal); + + await expect.soft(columns).toHaveCount(params.hideNumOccurrences ? 1 : 2); + await expect.soft(columns.nth(0)).toHaveText(params.columnName); + if (!params.hideNumOccurrences) { + await expect.soft(columns.nth(1)).toHaveText('Number of Occurrences'); + } + + }); + + if (!params.hideNumOccurrences) { + await test.step('numer of Occurrences column should be available and users should be able to sort based on that.', async () => { + const sortBtn = RecordsetLocators.getColumnSortButton(modal, 'count'); + await expect.soft(sortBtn).toBeVisible(); + + await sortBtn.click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + const columnValues = RecordsetLocators.getFirstColumn(modal); + await expect.soft(columnValues).toHaveCount(params.modalOptionsSortedByNumOfOccurences.length); + await expect.soft(columnValues).toHaveText(params.modalOptionsSortedByNumOfOccurences); + }); + } + + await test.step('should close the facet modal', async () => { + await ModalLocators.getCloseBtn(modal).click(); + }); + } + }); + + test('Records With Value (not-null) filter', async ({ page, baseURL }, testInfo) => { + const facet = RecordsetLocators.getFacetById(page, testParams.not_null.facetIdx); + + await test.step('should load recordset page and clear all filters', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + await test.step('`All Records with value` option must be available in facet panel.', async () => { + await RecordsetLocators.getFacetHeaderButtonById(facet, testParams.not_null.facetIdx).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + + // make sure facet is loaded + const facetOptions = RecordsetLocators.getFacetOptions(facet); + await expect.soft(facetOptions).toHaveCount(12); + await expect.soft(facetOptions).toHaveText(testParams.not_null.options_w_not_null); + }); + + await test.step('After clicking on `All records with value`, the rest of options must be disabled', async () => { + await RecordsetLocators.getFacetOption(facet, 0).check(); + + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(1) + + // same check as previous test to make sure displayed options don't change + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); + + await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(testParams.not_null.disabled_rows_w_not_null); + await expect(RecordsetLocators.getRows(page)).toHaveCount(testParams.not_null.result_num_w_not_null); + }); + + await test.step('Deselecting `All records with value` should enable all the values on the list.', async () => { + await RecordsetLocators.getFacetOption(facet, 0).uncheck(); + + // same check as previous 2 tests to make sure displayed options don't change again + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); + + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0); + await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(0); + }); + + await test.step('should be able to select other filters on the facet.', async () => { + await RecordsetLocators.getFacetOption(facet, 1).click(); + + // same check as previous 3 tests to make sure displayed options don't change again + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); + + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(1); + await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(0); + }); + + await test.step('Selecting `All records with value` in the list, should remove all the checked filters on facet.', async () => { + await RecordsetLocators.getFacetOption(facet, 0).check(); + + // same check as previous 4 tests to make sure displayed options don't change again + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); + + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(1); + await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(testParams.not_null.disabled_rows_w_not_null); + }); + }); + + test('No value (null) filter', async ({ page, baseURL }, testInfo) => { + await test.step('should load recordset page and clear all filters', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + await test.step('null should be provided as an option and user should be able to select it.', async () => { + const params = testParams.null_filter.panel; + const facet = RecordsetLocators.getFacetById(page, params.facetIdx); + + await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.totalNumOptions); + + await RecordsetLocators.getFacetOption(facet, params.option).click(); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); + + + // clear the selected facet + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + await test.step('regarding facets that require right join', async () => { + const params = testParams.null_filter.right_join; + + await test.step('null should be provided as an option and user should be able to select it.', async () => { + const facet = RecordsetLocators.getFacetById(page, params.firstFacet.idx); + await RecordsetLocators.getFacetHeaderButtonById(facet, params.firstFacet.idx).click(); + + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.firstFacet.totalNumOptions); + + await RecordsetLocators.getFacetOption(facet, params.firstFacet.option).check(); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.firstFacet.numRows); + }); + + await test.step('after selecting one, other such facets should not provide null option.', async () => { + const facet = RecordsetLocators.getFacetById(page, params.secondFacet.idx); + await openFacetAndTestFilterOptions( + page, + facet, + params.secondFacet.idx, + params.secondFacet.options, + 6 // 6 open facets + ); + }); + }); + }); + + /*********************************************************** local test cases ***********************************************************/ + if (process.env.CI) return; + // NOTE the following test cases will only run locally. + + test('regarding the logic to show only certain number of selected items', async ({ page, baseURL }, testInfo) => { + const params = testParams.hide_selected_items; + const facet1 = RecordsetLocators.getFacetById(page, params.firstFacet.index); + const facet2 = RecordsetLocators.getFacetById(page, params.secondFacet.index); + + await test.step('should load recordset page', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}/*::facets::${params.facetBlob}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + }); + + await test.step('facet panel should only show limited number of selected facet options.', async () => { + // wait for facet to open + await expect.soft(RecordsetLocators.getFacetCollapse(facet1)).toBeVisible(); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet1)).toBeVisible(); + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet1)).toHaveText(params.firstFacet.options); + + // make sure all are selected + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet1)).toHaveCount(params.firstFacet.options.length) + + // make sure the text is visible + await expect.soft(RecordsetLocators.getFacetMoreFiltersText(facet1)).toHaveText('2 selected items not displayed.'); + }); + + await test.step('interacting with other facet should rearrange the options and update the message.', async () => { + // deselect the first option in the first facet + await expect.soft(RecordsetLocators.getFacetSpinner(facet1)).not.toBeVisible(); + await RecordsetLocators.getFacetOption(facet1, 0).uncheck(); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet2)).toBeVisible(); + + // in the second facet, deselect third option (first two are not-null and null) + await expect.soft(RecordsetLocators.getFacetSpinner(facet2)).not.toBeVisible(); + await RecordsetLocators.getFacetOption(facet2, params.secondFacet.selectedOption).uncheck(); + // wait for facet checkboxes to load for the first facet + await expect.soft(RecordsetLocators.getFacetOptions(facet1)).toHaveText(params.firstFacet.optionsAfterFirstChange); + + // make sure all are selected + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet1)).toHaveCount(params.firstFacet.optionsAfterFirstChange.length); + // make sure the text is updated + await expect.soft(RecordsetLocators.getFacetMoreFiltersText(facet1)).toHaveText('1 selected items not displayed.'); + }); + + await test.step('going below the limit should remove the message.', async () => { + // deselect first and second options in the first facet so we go below the limit + await expect.soft(RecordsetLocators.getFacetSpinner(facet1)).not.toBeVisible(); + await RecordsetLocators.getFacetOption(facet1, 0).uncheck(); + + await expect.soft(RecordsetLocators.getFacetSpinner(facet1)).not.toBeVisible(); + await RecordsetLocators.getFacetOption(facet1, 1).uncheck(); + + // in the second facet, deselect third option (first two are not-null and null) + await expect.soft(RecordsetLocators.getFacetSpinner(facet2)).not.toBeVisible(); + await RecordsetLocators.getFacetOption(facet2, params.secondFacet.selectedOption).uncheck(); + + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet1)).toHaveText(params.firstFacet.optionsAfterFinalChange); + + // make sure the text has disapeared + await expect.soft(RecordsetLocators.getFacetMoreFiltersText(facet1)).not.toBeVisible(); + }); + }); + + test('regarding facets with shared path', async ({ page, baseURL }, testInfo) => { + const params = testParams.shared_path_prefix; + + await test.step('should load recordset page', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}/*::facets::${params.facetBlob}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); + }); + + await test.step('for the facet with subset path', async () => { + await testFacetOptions( + page, + params.firstFacet.index, + params.firstFacet.options, + params.firstFacet.modalOptions + ); + }); + + await test.step('for the facet with superset path', async () => { + await testFacetOptions( + page, + params.secondFacet.index, + params.secondFacet.options, + params.secondFacet.modalOptions + ); + }); + }); + + test('regarding UnsupportedFilters handling', async ({ page, baseURL }, testInfo) => { + const params = testParams.unsupported_filters_error; + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + const modal = ModalLocators.getErrorModal(page); + + await test.step('should load recordset page', async () => { + await page.goto(`${baseURL}${PAGE_URL}/*::facets::${params.facetBlob}`); + await expect.soft(modal).toBeVisible(); + }); + + await test.step('Proper error should be displayed', async () => { + await expect.soft(ModalLocators.getModalTitle(modal)).toHaveText('Unsupported Filters'); + }); + + await test.step('Error modal message must summarize the issue', async () => { + await expect.soft(ModalLocators.getModalText(modal)).toHaveText(params.errorMessage); + }); + + await test.step('Error modal should Show Error Details', async () => { + const showDetails = ModalLocators.getToggleErrorDetailsButton(modal); + const errorDetails = ModalLocators.getErrorDetails(modal); + + await showDetails.click() + await expect.soft(errorDetails).toBeVisible(); + + await expect.soft(showDetails).toHaveText('Hide Error Details'); + await expect.soft(errorDetails).toHaveText(params.errorDetails); + }); + + await test.step('On click of OK button the page should dismiss the error and show proper results', async () => { + // close show details message so OK button is in the viewport again (modal doesn't have a scrollbar when it's expanded below viewport) + await ModalLocators.getToggleErrorDetailsButton(modal).click(); + await ModalLocators.getOkButton(modal).click(); + + // make sure it's showing proper number of values + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); + + // @sort(RID) gets appended by the app + const newURL = `${baseURL}${PAGE_URL}/*::facets::${params.facetBlobAfterOK}@sort(RID)`; + await expect.soft(page).toHaveURL(newURL); + }); + }); + + test('regarding hide_row_count support in entity facet popups', async ({ page, baseURL }, testInfo) => { + await test.step('should load recordset page and clear all filters', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + await test.step('should hide the total count when hide_row_count=true', async () => { + const params = testParams.hide_row_count.hidden; + const facet = RecordsetLocators.getFacetById(page, params.facetIdx); + const modal = ModalLocators.getRecordsetSearchPopup(page); + + // facet is already open so we don't have to click to open + await RecordsetLocators.getShowMore(facet).click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + await expect.soft(RecordsetLocators.getFirstColumn(modal)).toHaveCount(params.numModalOptions); + await expect.soft(RecordsetLocators.getTotalCount(modal)).toHaveText(params.displayingText); + + await ModalLocators.getCloseBtn(modal).click(); + }); + + await test.step('otherwise should show the total count', async () => { + const params = testParams.hide_row_count.shown; + const facet = RecordsetLocators.getFacetById(page, params.facetIdx); + const modal = ModalLocators.getRecordsetSearchPopup(page); + + // open the facet first and then open the modal + await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + + await RecordsetLocators.getShowMore(facet).click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + await expect.soft(RecordsetLocators.getFirstColumn(modal)).toHaveCount(params.numModalOptions); + await expect.soft(RecordsetLocators.getTotalCount(modal)).toHaveText(params.displayingText); + + await ModalLocators.getCloseBtn(modal).click(); + }); + }); + + test('navigating to recordset with filters that faceting doesn\'t support', async ({ page, baseURL }, testInfo) => { + const params = testParams.customFilter; + const facet = RecordsetLocators.getFacetById(page, params.facet); + + await test.step('should load recordset page', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}/${params.ermrestFilter}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + }); + + await test.step('should show the applied filter and clear all button.', async () => { + const facetFilters = RecordsetLocators.getFacetFilters(page); + await expect.soft(facetFilters).toHaveCount(1); + + await expect.soft(facetFilters.nth(0)).toHaveText(`Custom Filter${params.ermrestFilterDisplayed}`) + + await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); + }); + + await test.step('main and faceting data should be based on the filter, and be able to apply new filters.', async () => { + // main + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); + + await RecordsetLocators.getFacetHeaderButtonById(facet, params.facet).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.totalNumOptions); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); + + /** + * NOTE: this was getFacetOptionsText in protractor because for some reason the .getText started returning empty + * value for the rows that are hidden because of the height logic + * + * This doesn't seem to be an issue anymore but leaving this comment in case this fails randomly later + */ + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.options); + + // select a new facet + await RecordsetLocators.getFacetOption(facet, params.option).check(); + + // wait for table rows to load + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRowsWFacet); + + // make sure filter is there + await expect.soft(RecordsetLocators.getFacetFilters(page)).toHaveCount(2); + }); + + await test.step('clicking on `x` for Custom Filter should only clear the filter.', async () => { + const customFiltersBtn = RecordsetLocators.getClearCustomFilters(page); + await expect.soft(customFiltersBtn).toBeVisible(); + await customFiltersBtn.click(); + + await RecordsetLocators.waitForRecordsetPageReady(page); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRowsWOFilter); + + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.optionsWOFilter.length); + + /** + * NOTE: this was getFacetOptionsText in protractor because for some reason the .getText started returning empty + * value for the rows that are hidden because of the height logic + * + * This doesn't seem to be an issue anymore but leaving this comment in case this fails randomly later + */ + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.optionsWOFilter); + }); + }); + + test('regarding URL limitation check', async ({ page, baseURL }, testInfo) => { + const params = testParams.maximumLength; + const alert = AlertLocators.getWarningAlert(page); + + const checkAlert = async (alert: Locator) => { + await expect.soft(alert).toBeVisible(); + await expect.soft(alert).toHaveText('WarningMaximum URL length reached. Cannot perform the requested action.'); + }; + + await test.step('should load recordset page, clear all filters,, and close the open facets', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + + const facet1 = RecordsetLocators.getFacetById(page, 0); + await RecordsetLocators.getFacetHeaderButtonById(facet1, 0).click(); + + const facet2 = RecordsetLocators.getFacetById(page, 2); + await RecordsetLocators.getFacetHeaderButtonById(facet2, 2).click(); + }); + + await test.step('searching a lenghty string should show the `Maximum URL length reached` warning.', async () => { + const mainSearch = RecordsetLocators.getMainSearchInput(page); + + const chanceObj = new chance(); + await mainSearch.fill(chanceObj.string({length: 4000})); + await RecordsetLocators.waitForRecordsetPageReady(page); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); + await checkAlert(alert); + }); + + await test.step('in facet modal', async () => { + const facet = RecordsetLocators.getFacetById(page, params.facetIdx); + const modal = ModalLocators.getRecordsetSearchPopup(page); + const modalAlert = AlertLocators.getWarningAlert(modal); + + await test.step('open the facet then open the show more modal', async () => { + await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + + await RecordsetLocators.getShowMore(facet).click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + }); + + await test.step('after opening the modal, the existing url limit alert should be removed.', async () => { + await expect.soft(modalAlert).not.toBeAttached(); + }); + + + }); + }); +}); \ No newline at end of file diff --git a/test/e2e/utils/chaise.page.js b/test/e2e/utils/chaise.page.js index a8c902cec..8e02b6de0 100644 --- a/test/e2e/utils/chaise.page.js +++ b/test/e2e/utils/chaise.page.js @@ -1026,7 +1026,7 @@ var recordsetPage = function() { }; /** - * TODO in playwright version, use rdsetLocators.getRows(rsModal) + * TODO in playwright version, use recordsetLocators.getRows(rsModal) */ this.getModalRows = function () { return element.all(by.css('.modal-body .chaise-table-row')); @@ -1037,7 +1037,7 @@ var recordsetPage = function() { }; this.waitForInverseModalSpinner = function () { - var locator = element(by.css(".modal-body .recordest-main-spinner")); + var locator = element(by.css(".modal-body .recordset-main-spinner")); return browser.wait(protractor.ExpectedConditions.invisibilityOf(locator), browser.params.defaultTimeout); }; diff --git a/test/e2e/utils/recordset-utils.ts b/test/e2e/utils/recordset-utils.ts index b92255b80..cd3cb50b5 100644 --- a/test/e2e/utils/recordset-utils.ts +++ b/test/e2e/utils/recordset-utils.ts @@ -1,4 +1,7 @@ import { expect, Locator, Page, test } from '@playwright/test' + +// locators +import ModalLocators from '@isrd-isi-edu/chaise/test/e2e/locators/modal'; import RecordsetLocators, { DefaultRangeInputLocators, TimestampRangeInputLocators @@ -240,6 +243,8 @@ export async function testTimestampRangePickerInputsAfterZoom( await testInputValue(false, rangeInputs.maxTimeInput, max.time); } +/** Reusable Test Steps **/ + /** * this is done in multiple places for facet specs. it will reset the state of the page. * @param page the page object @@ -276,4 +281,30 @@ export async function openRecordsetAndResetFacetState( await expect.soft(closedFacets).toHaveCount(totalNumFacets - openedFacets.length + i + 1); } }); +} + +export async function testFacetOptions(page: Page, facetIdx: number, filterOptions: string[], modalOptions: string[]) { + const facet = RecordsetLocators.getFacetById(page, facetIdx); + + await test.step('the facet options should be correct', async () => { + // wait for facet to open + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(filterOptions) + }); + + await test.step('opening the facet modal should show the correct rows.', async () => { + // click on show more + await RecordsetLocators.getShowMore(facet).click(); + + const modal = ModalLocators.getRecordsetSearchPopup(page); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + // this will wait for the list to be the same as expected, otherwise will timeout + await expect.soft(RecordsetLocators.getFirstColumn(modal)).toHaveText(modalOptions); + + await ModalLocators.getCloseBtn(modal).click(); + }); } \ No newline at end of file From 80660e11225c55d752f4750f279399148b91f96a Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Thu, 27 Jun 2024 11:23:32 -0700 Subject: [PATCH 02/12] more tests for misc-facet spec. Last test fails when trying to run them locally with an error from ermrestJS --- test/e2e/locators/recordedit.ts | 4 + test/e2e/locators/recordset.ts | 5 + .../recordset/misc-facet.spec.ts | 297 ++++++++++++++++-- 3 files changed, 284 insertions(+), 22 deletions(-) diff --git a/test/e2e/locators/recordedit.ts b/test/e2e/locators/recordedit.ts index 1a7dfc766..fabb869c1 100644 --- a/test/e2e/locators/recordedit.ts +++ b/test/e2e/locators/recordedit.ts @@ -256,6 +256,10 @@ export default class RecordeditLocators { return RecordeditLocators.getForeignKeyInputDisplay(container, columnDisplayName, formNumber).locator('.remove-input-btn'); } + static getModalPopupButtons(container: Page | Locator): Locator { + return container.locator('.modal-popup-btn'); + } + // ----------------- multi form input selectors ------------------- // diff --git a/test/e2e/locators/recordset.ts b/test/e2e/locators/recordset.ts index c1464d9f3..573511630 100644 --- a/test/e2e/locators/recordset.ts +++ b/test/e2e/locators/recordset.ts @@ -163,6 +163,11 @@ export default class RecordsetLocators { return container.locator('.chaise-table-row td:nth-child(2)'); } + // Currently only in modals but could be part of recordset in different contexts/views + static getSelectAllBtn(container: Page | Locator): Locator { + return container.locator('.table-select-all-rows') + }; + /* sort selectors */ static getColumnSortButton(container: Page | Locator, rawColumnName: string): Locator { return container.locator(`.c_${rawColumnName} .not-sorted-icon`); diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index 19f202941..faa02b2ba 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -4,11 +4,14 @@ import chance from 'chance'; // locators import AlertLocators from '@isrd-isi-edu/chaise/test/e2e/locators/alert'; import ModalLocators from '@isrd-isi-edu/chaise/test/e2e/locators/modal'; +import RecordLocators from '@isrd-isi-edu/chaise/test/e2e/locators/record'; +import RecordeditLocators from '@isrd-isi-edu/chaise/test/e2e/locators/recordedit'; import RecordsetLocators from '@isrd-isi-edu/chaise/test/e2e/locators/recordset'; // utils import { getCatalogID } from '@isrd-isi-edu/chaise/test/e2e/utils/catalog-utils'; -import { openFacetAndTestFilterOptions, testFacetOptions } from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; +import { testRecordMainSectionValues } from '@isrd-isi-edu/chaise/test/e2e/utils/record-utils'; +import { openFacet, openFacetAndTestFilterOptions, testFacetOptions } from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; const testParams = { schema_name: 'faceting', @@ -124,22 +127,16 @@ const testParams = { }, recordColumns: [ 'text_col', 'longtext_col', 'markdown_col', 'int_col', 'float_col', 'date_col', 'timestamp_col', - 'boolean_col', 'jsonb_col', '1-o7Ye2EkulrWcCVFNHi3A', 'hmZyP_Ufo3E5v_nmdTXyyA' + 'boolean_col', 'jsonb_col', 'fk_to_f1', 'to_name' ], - recordValues: { - text_col: 'one', + recordValues: [ + 'one', // eslint-disable-next-line max-len - longtext_col: 'lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod.', - markdown_col: 'one', - int_col: '11', - float_col: '11.1100', - date_col: '2001-01-01', - timestamp_col: '2001-01-01 00:01:01', - boolean_col: 'true', - jsonb_col: JSON.stringify({ 'key': 'one' }, undefined, 2), - '1-o7Ye2EkulrWcCVFNHi3A': 'one', // faceting_main_fk1 - 'hmZyP_Ufo3E5v_nmdTXyyA': 'one' // faceting_main_fk2 - }, + 'lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod.', + 'one', '11', '11.1100', '2001-01-01', '2001-01-01 00:01:01', + 'true', JSON.stringify({ 'key': 'one' }, undefined, 2), 'one', // faceting_main_fk1 + 'one' // faceting_main_fk2 + ], shared_path_prefix: { facetObject: { 'and': [ @@ -244,9 +241,9 @@ const testParams = { }, hideFilterPanelClass: 'chaise-sidebar-close', showFilterPanelClass: 'chaise-sidebar-open', - foreignKeyPopupFacetFilter: 'term\neight', + foreignKeyPopupFacetFilter: 'termeight', associationRTName: 'main_f3_assoc', - associationPopupFacetFilter: 'term\nfive', + associationPopupFacetFilter: 'termfive', associationPopupSelectedRowsFilter: 'five' }; @@ -814,13 +811,14 @@ test.describe('Other facet features', () => { test('regarding URL limitation check', async ({ page, baseURL }, testInfo) => { const params = testParams.maximumLength; const alert = AlertLocators.getWarningAlert(page); + const facet1 = RecordsetLocators.getFacetById(page, params.facetIdx); const checkAlert = async (alert: Locator) => { await expect.soft(alert).toBeVisible(); await expect.soft(alert).toHaveText('WarningMaximum URL length reached. Cannot perform the requested action.'); }; - await test.step('should load recordset page, clear all filters,, and close the open facets', async () => { + await test.step('should load recordset page, clear all filters, and close the open facets', async () => { const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; await page.goto(`${baseURL}${PAGE_URL}`); @@ -851,23 +849,278 @@ test.describe('Other facet features', () => { }); await test.step('in facet modal', async () => { - const facet = RecordsetLocators.getFacetById(page, params.facetIdx); const modal = ModalLocators.getRecordsetSearchPopup(page); const modalAlert = AlertLocators.getWarningAlert(modal); + const modalSubmit = ModalLocators.getSubmitButton(modal); await test.step('open the facet then open the show more modal', async () => { - await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + await RecordsetLocators.getFacetHeaderButtonById(facet1, params.facetIdx).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet1)).toBeVisible(); - await RecordsetLocators.getShowMore(facet).click(); + await RecordsetLocators.getShowMore(facet1).click(); await RecordsetLocators.waitForRecordsetPageReady(modal); }); await test.step('after opening the modal, the existing url limit alert should be removed.', async () => { await expect.soft(modalAlert).not.toBeAttached(); }); + + await test.step('alert should be displayed upon reaching the URL limit and submit button should be disabled.', async () => { + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(25); + + await RecordsetLocators.getSelectAllBtn(modal).click(); + await checkAlert(modalAlert); + + await expect.soft(modalSubmit).toHaveAttribute('disabled'); + }); + + await test.step('changing filters and going below the URL limit should hide the alert and enable the submit button.', async () => { + await RecordsetLocators.getCheckboxInputs(modal).nth(0).uncheck(); + + await expect.soft(modalAlert).not.toBeAttached(); + await expect.soft(modalSubmit).not.toHaveAttribute('disabled'); + + await modalSubmit.click(); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.filteredNumRows); + }); + }); + + await test.step('in main container', async () => { + const secondFacetIdx = params.secondFacetIdx; + const facet2 = RecordsetLocators.getFacetById(page, params.secondFacetIdx); + + await test.step('alert should be displayed upon reaching the URL limit and the request should not be completed.', async () => { + await openFacet(page, facet2, secondFacetIdx, params.secondFacetNumOptions, 5); + + const facetOption = RecordsetLocators.getFacetOption(facet2, params.secondFacetOption); + // trying to "click" this option will result in the alert being shown and the checkbox NOT being checked + // using .click() since .check() verifies the state of the checkbox has changed and we don't allow the state to change + await facetOption.click(); + await checkAlert(alert); + await expect.soft(facetOption).not.toBeChecked(); + }); + + await test.step('changing filters and going below the URL limit should hide the alert.', async () => { + await RecordsetLocators.getFacetOption(facet1, params.option).uncheck(); + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.maximumLength.filteredNumRows - 1); + + await expect.soft(alert).not.toBeAttached(); + }); + }); + }); + + test.describe('navigating to record and recordedit app with facets', () => { + test('from recordset app with multiple records', async ({ page, baseURL }, testInfo) => { + await test.step('should load recordset page and clear all filters', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + + const clearAll = RecordsetLocators.getClearAllFilters(page); + await clearAll.click(); + await expect.soft(clearAll).not.toBeVisible(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + }); + + await test.step('clicking bulk edit should show the same number of forms in RE as rows in RS.', async () => { + await RecordsetLocators.getBulkEditLink(page).click(); + await RecordeditLocators.waitForRecordeditPageReady(page); + + await expect.soft(RecordeditLocators.getRecordeditForms(page)).toHaveCount(25); + }); + }); + + test('in recordedit app, foreign key popup should have facets available', async ({ page, baseURL }, testInfo) => { + const modal = ModalLocators.getRecordsetSearchPopup(page); + + await test.step('should load recordset page, wait for `facets` to be added to the url, and change to recordedit app', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); + + await expect.soft(page).toHaveURL(/facets/); + + const url = page.url(); + await page.goto(url.replace('recordset', 'recordedit')); + await RecordeditLocators.waitForRecordeditPageReady(page); + }); + + await test.step('should click the foreign key popup button and have the facet collapse button visible in search popup', async () => { + await expect.soft(RecordeditLocators.getRecordeditForms(page)).toHaveCount(1); + + // open the first fk popup + await RecordeditLocators.getModalPopupButtons(page).nth(0).click(); + + await expect.soft(ModalLocators.getModalTitle(modal)).toBeVisible(); + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(13); + + // make sure side bar is hidden + await expect.soft(RecordsetLocators.getSidePanel(modal)).not.toBeVisible(); + // make sure 'show' filter panel button is shown + await expect.soft(RecordsetLocators.getShowFilterPanelBtn(modal)).toBeVisible(); + }); + + // NOTE: identical to a test below + await test.step('clicking the side panel button should open the facet panel', async () => { + await RecordsetLocators.getShowFilterPanelBtn(modal).click(); + + // make sure side bar is shown + await expect.soft(RecordsetLocators.getSidePanel(modal)).toBeVisible(); + // make sure 'hide' filter panel button is shown + await expect.soft(RecordsetLocators.getHideFilterPanelBtn(modal)).toBeVisible(); + }); + + await test.step('select a facet option and select a row for the input', async () => { + const facet = RecordsetLocators.getFacetById(modal, 0); + await RecordsetLocators.getFacetOption(facet, 0).click(); + + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(1); + await expect.soft(RecordsetLocators.getFacetFilters(modal).nth(0)).toHaveText(testParams.foreignKeyPopupFacetFilter); + + const selectButtons = RecordsetLocators.getRows(modal).locator('.select-action-button'); + await expect.soft(selectButtons).toHaveCount(1); + + await selectButtons.nth(0).click(); + await expect.soft(RecordeditLocators.getPageTitle(page)).toBeVisible(); + + await expect.soft(RecordeditLocators.getForeignKeyInputDisplay(page,'fk_to_f1', 1)).toHaveText('eight'); + }); + }); + + test('in record app, association add popup should have facets available', async ({ page, baseURL }, testInfo) => { + const modal = ModalLocators.getRecordsetSearchPopup(page); + + await test.step('should load recordset page, wait for `facets` to be added to the url, and change to record app', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}`); + await RecordsetLocators.waitForRecordsetPageReady(page); + await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); + + await expect.soft(page).toHaveURL(/facets/); + + const url = page.url(); + await page.goto(url.replace('recordset', 'record')); + await RecordLocators.waitForRecordPageReady(page); + }); + + await test.step('navigating to record with a facet url', async () => { + await testRecordMainSectionValues(page, testParams.recordColumns, testParams.recordValues); + }); + + await test.step('should click the add button for an association table and have the facet collapse button visible', async () => { + await RecordLocators.getRelatedTableAddButton(page, testParams.associationRTName, false).click(); + + await expect.soft(ModalLocators.getModalTitle(modal)).toBeVisible(); + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(5); + + // make sure side bar is hidden + await expect.soft(RecordsetLocators.getSidePanel(modal)).not.toBeVisible(); + // make sure 'show' filter panel button is shown + await expect.soft(RecordsetLocators.getShowFilterPanelBtn(modal)).toBeVisible(); + }); + + // NOTE: identical to a test above + await test.step('clicking the side panel button should open the facet panel', async () => { + await RecordsetLocators.getShowFilterPanelBtn(modal).click(); + // make sure side bar is shown + await expect.soft(RecordsetLocators.getSidePanel(modal)).toBeVisible(); + // make sure 'hide' filter panel button is shown + await expect.soft(RecordsetLocators.getHideFilterPanelBtn(modal)).toBeVisible(); + }); + + await test.step('select a facet option and select a row to associate', async () => { + const facet = RecordsetLocators.getFacetById(modal, 0); + await RecordsetLocators.getFacetOption(facet, 0).click(); + + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(1); + await expect.soft(RecordsetLocators.getFacetFilters(modal).nth(0)).toHaveText(testParams.associationPopupFacetFilter); + + await RecordsetLocators.getCheckboxInputs(modal).check(); + + // verify selected row filter + await expect.soft(RecordsetLocators.getSelectedRowsFilters(modal).nth(0)).toHaveText(testParams.associationPopupSelectedRowsFilter); + // NOTE: we don't test add here because we aren't trying to test mutating data, but rather that the popup behaves appropriately with faceting + }); + }); + }); + + test('navigating to recordset with custom facet', async ({ page, baseURL }, testInfo) => { + const params = testParams.customFacet; + + await test.step('should load recordset page', async () => { + const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; + + await page.goto(`${baseURL}${PAGE_URL}/*::facets::${params.cfacetBlob}`); + await page.pause(); + await RecordsetLocators.waitForRecordsetPageReady(page); + }); + + await test.step('should show the applied filter and clear all button.', async () => { + const facetFilters = RecordsetLocators.getFacetFilters(page); + await expect.soft(facetFilters).toHaveCount(1); + await expect.soft(facetFilters.nth(0)).toHaveText(`Custom Filter${params.cfacet.displayname}`); + await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); }); + + // await test.step('main and faceting data should be based on the filter, and be able to apply new filters.', async () => { + // browser.wait(function () { + // return chaisePage.recordsetPage.getRows().count().then(function(ct) { + // return ct == customFacetParams.numRows; + // }); + // }, browser.params.defaultTimeout); + // // main + // expect(chaisePage.recordsetPage.getRows().count()).toEqual(customFacetParams.numRows, "total row count missmatch."); + + // chaisePage.clickButton(chaisePage.recordsetPage.getFacetHeaderButtonById(idx)).then(function () { + // browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); + + // // wait for facet checkboxes to load + // browser.wait(function () { + // return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { + // return ct == customFacetParams.totalNumOptions; + // }); + // }, browser.params.defaultTimeout); + + // // wait for list to be fully visible + // browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(idx)), browser.params.defaultTimeout); + + // /** + // * NOTE: this used to be getFacetOptions, but for some reason the .getText started returning empty + // * value for the rows that are hidden because of the height logic + // * so I changed it to directly get the text from javascript. + // */ + // return chaisePage.recordsetPage.getFacetOptionsText(idx); + // }).then(function (opts) { + // opts.forEach(function (option, i) { + // expect(option).toEqual(customFacetParams.options[i], `options missmatch, index=${i}`); + // }); + + // // select a new facet + // return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(idx, customFacetParams.option)); + // }).then(function () { + // // wait for table rows to load + // browser.wait(function () { + // return chaisePage.recordsetPage.getRows().count().then(function(ct) { + // return ct == customFacetParams.numRowsWFacet; + // }); + // }, browser.params.defaultTimeout); + + // // make sure data has been updated + // expect(chaisePage.recordsetPage.getRows().count()).toBe(customFacetParams.numRowsWFacet, ""); + + // // make sure filter is there + // expect(chaisePage.recordsetPage.getFacetFilters().count()).toBe(2, "facet filter missing."); + + + // done(); + // }).catch(chaisePage.catchTestError(done)); + // }); }); }); \ No newline at end of file From 4e50282f73a7370e2da73e7f4a48819bde0d8f66 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Fri, 28 Jun 2024 13:46:42 -0700 Subject: [PATCH 03/12] use cfacets --- test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index faa02b2ba..70f8589df 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -1056,7 +1056,7 @@ test.describe('Other facet features', () => { await test.step('should load recordset page', async () => { const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; - await page.goto(`${baseURL}${PAGE_URL}/*::facets::${params.cfacetBlob}`); + await page.goto(`${baseURL}${PAGE_URL}/*::cfacets::${params.cfacetBlob}`); await page.pause(); await RecordsetLocators.waitForRecordsetPageReady(page); }); From e560ae6dd23acc5b46f7ba0754b9b753acf8045f Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Fri, 28 Jun 2024 16:09:51 -0700 Subject: [PATCH 04/12] finish migration of misc facet spec. unccomment condition to run tests in CI --- .../recordset/misc-facet.spec.ts | 127 ++++++++---------- 1 file changed, 58 insertions(+), 69 deletions(-) diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index 70f8589df..a328da2f5 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -547,7 +547,7 @@ test.describe('Other facet features', () => { }); /*********************************************************** local test cases ***********************************************************/ - if (process.env.CI) return; + // if (process.env.CI) return; // NOTE the following test cases will only run locally. test('regarding the logic to show only certain number of selected items', async ({ page, baseURL }, testInfo) => { @@ -839,11 +839,11 @@ test.describe('Other facet features', () => { await test.step('searching a lenghty string should show the `Maximum URL length reached` warning.', async () => { const mainSearch = RecordsetLocators.getMainSearchInput(page); - + const chanceObj = new chance(); - await mainSearch.fill(chanceObj.string({length: 4000})); + await mainSearch.fill(chanceObj.string({ length: 4000 })); await RecordsetLocators.waitForRecordsetPageReady(page); - + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); await checkAlert(alert); }); @@ -864,7 +864,7 @@ test.describe('Other facet features', () => { await test.step('after opening the modal, the existing url limit alert should be removed.', async () => { await expect.soft(modalAlert).not.toBeAttached(); }); - + await test.step('alert should be displayed upon reaching the URL limit and submit button should be disabled.', async () => { await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(25); @@ -879,7 +879,7 @@ test.describe('Other facet features', () => { await expect.soft(modalAlert).not.toBeAttached(); await expect.soft(modalSubmit).not.toHaveAttribute('disabled'); - + await modalSubmit.click(); await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.filteredNumRows); }); @@ -903,7 +903,7 @@ test.describe('Other facet features', () => { await test.step('changing filters and going below the URL limit should hide the alert.', async () => { await RecordsetLocators.getFacetOption(facet1, params.option).uncheck(); await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.maximumLength.filteredNumRows - 1); - + await expect.soft(alert).not.toBeAttached(); }); }); @@ -916,18 +916,18 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - + const clearAll = RecordsetLocators.getClearAllFilters(page); await clearAll.click(); await expect.soft(clearAll).not.toBeVisible(); - + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); }); await test.step('clicking bulk edit should show the same number of forms in RE as rows in RS.', async () => { await RecordsetLocators.getBulkEditLink(page).click(); await RecordeditLocators.waitForRecordeditPageReady(page); - + await expect.soft(RecordeditLocators.getRecordeditForms(page)).toHaveCount(25); }); }); @@ -986,8 +986,8 @@ test.describe('Other facet features', () => { await selectButtons.nth(0).click(); await expect.soft(RecordeditLocators.getPageTitle(page)).toBeVisible(); - - await expect.soft(RecordeditLocators.getForeignKeyInputDisplay(page,'fk_to_f1', 1)).toHaveText('eight'); + + await expect.soft(RecordeditLocators.getForeignKeyInputDisplay(page, 'fk_to_f1', 1)).toHaveText('eight'); }); }); @@ -1014,12 +1014,12 @@ test.describe('Other facet features', () => { await test.step('should click the add button for an association table and have the facet collapse button visible', async () => { await RecordLocators.getRelatedTableAddButton(page, testParams.associationRTName, false).click(); - + await expect.soft(ModalLocators.getModalTitle(modal)).toBeVisible(); await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(5); // make sure side bar is hidden - await expect.soft(RecordsetLocators.getSidePanel(modal)).not.toBeVisible(); + await expect.soft(RecordsetLocators.getSidePanel(modal)).not.toBeVisible(); // make sure 'show' filter panel button is shown await expect.soft(RecordsetLocators.getShowFilterPanelBtn(modal)).toBeVisible(); }); @@ -1042,7 +1042,7 @@ test.describe('Other facet features', () => { await expect.soft(RecordsetLocators.getFacetFilters(modal).nth(0)).toHaveText(testParams.associationPopupFacetFilter); await RecordsetLocators.getCheckboxInputs(modal).check(); - + // verify selected row filter await expect.soft(RecordsetLocators.getSelectedRowsFilters(modal).nth(0)).toHaveText(testParams.associationPopupSelectedRowsFilter); // NOTE: we don't test add here because we aren't trying to test mutating data, but rather that the popup behaves appropriately with faceting @@ -1052,6 +1052,7 @@ test.describe('Other facet features', () => { test('navigating to recordset with custom facet', async ({ page, baseURL }, testInfo) => { const params = testParams.customFacet; + const facet = RecordsetLocators.getFacetById(page, params.facet); await test.step('should load recordset page', async () => { const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; @@ -1064,63 +1065,51 @@ test.describe('Other facet features', () => { await test.step('should show the applied filter and clear all button.', async () => { const facetFilters = RecordsetLocators.getFacetFilters(page); await expect.soft(facetFilters).toHaveCount(1); - + await expect.soft(facetFilters.nth(0)).toHaveText(`Custom Filter${params.cfacet.displayname}`); await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); }); - // await test.step('main and faceting data should be based on the filter, and be able to apply new filters.', async () => { - // browser.wait(function () { - // return chaisePage.recordsetPage.getRows().count().then(function(ct) { - // return ct == customFacetParams.numRows; - // }); - // }, browser.params.defaultTimeout); - // // main - // expect(chaisePage.recordsetPage.getRows().count()).toEqual(customFacetParams.numRows, "total row count missmatch."); - - // chaisePage.clickButton(chaisePage.recordsetPage.getFacetHeaderButtonById(idx)).then(function () { - // browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); - - // // wait for facet checkboxes to load - // browser.wait(function () { - // return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { - // return ct == customFacetParams.totalNumOptions; - // }); - // }, browser.params.defaultTimeout); - - // // wait for list to be fully visible - // browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(idx)), browser.params.defaultTimeout); - - // /** - // * NOTE: this used to be getFacetOptions, but for some reason the .getText started returning empty - // * value for the rows that are hidden because of the height logic - // * so I changed it to directly get the text from javascript. - // */ - // return chaisePage.recordsetPage.getFacetOptionsText(idx); - // }).then(function (opts) { - // opts.forEach(function (option, i) { - // expect(option).toEqual(customFacetParams.options[i], `options missmatch, index=${i}`); - // }); - - // // select a new facet - // return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(idx, customFacetParams.option)); - // }).then(function () { - // // wait for table rows to load - // browser.wait(function () { - // return chaisePage.recordsetPage.getRows().count().then(function(ct) { - // return ct == customFacetParams.numRowsWFacet; - // }); - // }, browser.params.defaultTimeout); - - // // make sure data has been updated - // expect(chaisePage.recordsetPage.getRows().count()).toBe(customFacetParams.numRowsWFacet, ""); - - // // make sure filter is there - // expect(chaisePage.recordsetPage.getFacetFilters().count()).toBe(2, "facet filter missing."); - - - // done(); - // }).catch(chaisePage.catchTestError(done)); - // }); + await test.step('main and faceting data should be based on the filter, and be able to apply new filters.', async () => { + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); + + await RecordsetLocators.getFacetHeaderButtonById(facet, params.facet).click(); + await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + + // wait for facet checkboxes to load + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.totalNumOptions); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); + + /** + * NOTE: this was getFacetOptionsText in protractor because for some reason the .getText started returning empty + * value for the rows that are hidden because of the height logic + * + * This doesn't seem to be an issue anymore but leaving this comment in case this fails randomly later + */ + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.options); + + await RecordsetLocators.getFacetOption(facet, params.option).check(); + // wait for table rows to load + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRowsWFacet); + // make sure filter is there + await expect.soft(RecordsetLocators.getFacetFilters(page)).toHaveCount(2); + }); + + await test.step('clicking on `x` for Custom Filter should only clear the filter.', async () => { + await RecordsetLocators.getClearCustomFacets(page).click(); + // wait for table rows to load + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRowsWOCustomFacet); + // wait for list to be fully visible + await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); + + /** + * NOTE: this was getFacetOptionsText in protractor because for some reason the .getText started returning empty + * value for the rows that are hidden because of the height logic + * + * This doesn't seem to be an issue anymore but leaving this comment in case this fails randomly later + */ + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.optionsWOCustomFacet); + }); }); }); \ No newline at end of file From 8127eab8561a81932a2c8d73d90003871bb1578a Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Fri, 28 Jun 2024 16:10:10 -0700 Subject: [PATCH 05/12] run all facet specs --- .../specs/delete-prohibited/recordset/ind-facet.config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts b/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts index b03760225..5ddb8d6c4 100644 --- a/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts +++ b/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts @@ -5,9 +5,9 @@ export default getConfig({ configFileName: 'recordset/ind-facet.dev.json', mainSpecName: 'delete-prohibited', testMatch: [ - // 'facet-presentation.spec.ts', - // 'ind-facet.spec.ts', - // 'four-facet-selections.spec.ts', + 'facet-presentation.spec.ts', + 'ind-facet.spec.ts', + 'four-facet-selections.spec.ts', 'misc-facet.spec.ts' ] }); From bcd37baa3d6fb13c70b81611673aae3c4aa8fdf6 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Fri, 28 Jun 2024 18:41:19 -0700 Subject: [PATCH 06/12] refactored test cases, made a change for histogram-facet.spec to test if it fixes failures in CI --- .../recordset/histogram-facet.spec.ts | 4 +- .../recordset/ind-facet.spec.ts | 4 +- .../recordset/misc-facet.spec.ts | 297 +++++------------- test/e2e/utils/recordset-utils.ts | 48 ++- 4 files changed, 129 insertions(+), 224 deletions(-) diff --git a/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts index f6011a876..a94a101ee 100644 --- a/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/histogram-facet.spec.ts @@ -226,14 +226,14 @@ test.describe('Testing features for range picker facet types with histograms', ( await histogramButtons.zoom.click(); await expect.soft(RecordsetLocators.getFacetSpinner(facet)).not.toBeVisible(); + await expect.soft(histogramButtons.unzoomDisabled).toHaveCount(0); + await testRangePickerInputsAfterZoom( rangeInputs, isFloat, facetParams.zoom1.min as string, facetParams.zoom1.max as string ); - - await expect.soft(histogramButtons.unzoomDisabled).toHaveCount(0); }); await test.step('zoom in again and submit the range filter should display the proper resultset.', async () => { diff --git a/test/e2e/specs/delete-prohibited/recordset/ind-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/ind-facet.spec.ts index ab9aa6688..f73f38b87 100644 --- a/test/e2e/specs/delete-prohibited/recordset/ind-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/ind-facet.spec.ts @@ -432,7 +432,7 @@ test.describe('Testing individual facet types', () => { // make sure submit is disabled await expect.soft(rangeInputs.submit).toHaveAttribute('disabled'); - await testClearAllFilters(page, facet, 0, testParams.defaults.pageSize); + await testClearAllFilters(page, testParams.defaults.pageSize, facet, 0); await testDefaultRangePickerInitialValues(rangeInputs, facetParams); // clear inputs @@ -547,7 +547,7 @@ test.describe('Testing individual facet types', () => { // make sure submit is disabled await expect.soft(rangeInputs.submit).toHaveAttribute('disabled'); - await testClearAllFilters(page, facet, 0, testParams.defaults.pageSize); + await testClearAllFilters(page, testParams.defaults.pageSize, facet, 0); await testTimestampRangePickerInitialValues(rangeInputs, facetParams); // clear the inputs diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index a328da2f5..d2be76a9d 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -11,7 +11,11 @@ import RecordsetLocators from '@isrd-isi-edu/chaise/test/e2e/locators/recordset' // utils import { getCatalogID } from '@isrd-isi-edu/chaise/test/e2e/utils/catalog-utils'; import { testRecordMainSectionValues } from '@isrd-isi-edu/chaise/test/e2e/utils/record-utils'; -import { openFacet, openFacetAndTestFilterOptions, testFacetOptions } from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; +import { + openFacet, openFacetAndTestFilterOptions, + testColumnSort, testClearAllFilters, testFacetOptions, + testSelectFacetOption, testShowMoreClick, testSubmitModalSelection +} from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; const testParams = { schema_name: 'faceting', @@ -30,6 +34,8 @@ const testParams = { { title: 'facet with order and column_order false for scalar', facetIdx: 20, + numFacetOptions: 8, + numOpenFacets: 4, modalOptions: ['01', '02', '03', '04', '05', '06', '07'], sortable: false, modalOptionsSortedByScalar: [], // for type errors @@ -40,6 +46,8 @@ const testParams = { { title: 'facet without order and hide_num_occurrences true', facetIdx: 21, + numFacetOptions: 11, + numOpenFacets: 5, modalOptions: ['01', '13', '12', '11', '10', '09', '08', '07', '06', '05', '04', '03', '02'], sortable: true, modalOptionsSortedByScalar: ['13', '12', '11', '10', '09', '08', '07', '06', '05', '04', '03', '02', '01'], @@ -260,11 +268,7 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); await test.step('Side panel should hide/show by clicking pull button', async () => { @@ -285,27 +289,27 @@ test.describe('Other facet features', () => { }); await test.step('should open the facet, select a value to filter on.', async () => { - await RecordsetLocators.getFacetHeaderButtonById(facet, testParams.filter_secondary_key.facetIdx).click(); - // wait for facet to open - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); - // wait for facet checkboxes to load - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(testParams.filter_secondary_key.totalNumOptions); - // wait for list to be fully visible - await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); - - await RecordsetLocators.getFacetOption(facet, testParams.filter_secondary_key.option).click(); + await openFacet( + page, + facet, + testParams.filter_secondary_key.facetIdx, + testParams.filter_secondary_key.totalNumOptions, + 4 // 3 facets open on page load + ); - // wait for request to return - await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.filter_secondary_key.numRows); + await testSelectFacetOption( + page, + facet, + testParams.filter_secondary_key.option, + testParams.filter_secondary_key.numRows, + 1 + ) }); - await test.step('the selected value should be selected on the modal.', async () => { - await RecordsetLocators.getShowMore(facet).click(); - await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(12); - - await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(1); + await test.step('the selected value should be selected in the modal.', async () => { + await testShowMoreClick(page, facet, modal, 12, 1); + await expect.soft(RecordsetLocators.getCheckboxInputs(modal).nth(testParams.filter_secondary_key.selectedModalOption)).toBeChecked(); }); @@ -314,23 +318,18 @@ test.describe('Other facet features', () => { const submit = ModalLocators.getSubmitButton(modal); await expect.soft(submit).toHaveText('Submit'); - await submit.click(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.filter_secondary_key.numRowsAfterModal); - await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(2); + await testSubmitModalSelection(page, facet, submit, testParams.filter_secondary_key.numRowsAfterModal, 2); }); await test.step('removing values in the modal should allow for submitting to remove the set of selected options for that facet.', async () => { - await RecordsetLocators.getShowMore(facet).click(); - await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(2); + await testShowMoreClick(page, facet, modal, 12, 2); // clear selections in modal to remove selections in facet await RecordsetLocators.getClearSelectedRows(modal).click(); await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(0); - await ModalLocators.getSubmitButton(modal).click(); - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(testParams.filter_secondary_key.removingOptionsNumRowsAfterModal); - await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0); + const submit = ModalLocators.getSubmitButton(modal); + await testSubmitModalSelection(page, facet, submit, testParams.filter_secondary_key.removingOptionsNumRowsAfterModal, 0); }); }); @@ -341,11 +340,7 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); for (const params of testParams.facet_order) { @@ -353,13 +348,11 @@ test.describe('Other facet features', () => { const modal = ModalLocators.getRecordsetSearchPopup(page); await test.step('the rows in the modal should honor the given order.', async () => { - await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); - - // wait for facet to open - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + await openFacet(page, facet, params.facetIdx, params.numFacetOptions, params.numOpenFacets); // click on show more - await RecordsetLocators.getShowMore(facet).click(); + await testShowMoreClick(page, facet, modal, params.modalOptions.length, 0); + const columnValues = RecordsetLocators.getFirstColumn(modal); await expect.soft(columnValues).toHaveCount(params.modalOptions.length); @@ -372,14 +365,7 @@ test.describe('Other facet features', () => { }); } else { await test.step('users should be able to change the sort to be based on the scalar column.', async () => { - const sortBtn = RecordsetLocators.getColumnSortButton(modal, '0'); - await expect.soft(sortBtn).toBeVisible(); - - await sortBtn.click(); - await RecordsetLocators.waitForRecordsetPageReady(modal); - - const columnValues = RecordsetLocators.getFirstColumn(modal); - await expect.soft(columnValues).toHaveText(params.modalOptionsSortedByScalar); + await testColumnSort(modal, '0', params.modalOptionsSortedByScalar); }); } @@ -396,15 +382,7 @@ test.describe('Other facet features', () => { if (!params.hideNumOccurrences) { await test.step('numer of Occurrences column should be available and users should be able to sort based on that.', async () => { - const sortBtn = RecordsetLocators.getColumnSortButton(modal, 'count'); - await expect.soft(sortBtn).toBeVisible(); - - await sortBtn.click(); - await RecordsetLocators.waitForRecordsetPageReady(modal); - - const columnValues = RecordsetLocators.getFirstColumn(modal); - await expect.soft(columnValues).toHaveCount(params.modalOptionsSortedByNumOfOccurences.length); - await expect.soft(columnValues).toHaveText(params.modalOptionsSortedByNumOfOccurences); + await testColumnSort(modal, 'count', params.modalOptionsSortedByNumOfOccurences); }); } @@ -415,7 +393,8 @@ test.describe('Other facet features', () => { }); test('Records With Value (not-null) filter', async ({ page, baseURL }, testInfo) => { - const facet = RecordsetLocators.getFacetById(page, testParams.not_null.facetIdx); + const params = testParams.not_null; + const facet = RecordsetLocators.getFacetById(page, params.facetIdx); await test.step('should load recordset page and clear all filters', async () => { const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; @@ -423,63 +402,48 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); await test.step('`All Records with value` option must be available in facet panel.', async () => { - await RecordsetLocators.getFacetHeaderButtonById(facet, testParams.not_null.facetIdx).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); - - // make sure facet is loaded - const facetOptions = RecordsetLocators.getFacetOptions(facet); - await expect.soft(facetOptions).toHaveCount(12); - await expect.soft(facetOptions).toHaveText(testParams.not_null.options_w_not_null); + await openFacetAndTestFilterOptions( + page, + facet, + params.facetIdx, + params.options_w_not_null, + 4 + ); }); - await test.step('After clicking on `All records with value`, the rest of options must be disabled', async () => { - await RecordsetLocators.getFacetOption(facet, 0).check(); + const testOptionChange = async (optionIdx: number, isCheck: boolean, numCheckedOptions: number, numDisabledOptions: number, numRows: number) => { + if (isCheck) { + await RecordsetLocators.getFacetOption(facet, optionIdx).check(); + } else { + await RecordsetLocators.getFacetOption(facet, optionIdx).uncheck(); + } - await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(1) + // don't need to be params since it's the same in all tests + await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.options_w_not_null); - // same check as previous test to make sure displayed options don't change - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(numCheckedOptions); + await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(numDisabledOptions); + await expect(RecordsetLocators.getRows(page)).toHaveCount(numRows); + } - await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(testParams.not_null.disabled_rows_w_not_null); - await expect(RecordsetLocators.getRows(page)).toHaveCount(testParams.not_null.result_num_w_not_null); + await test.step('After clicking on `All records with value`, the rest of options must be disabled', async () => { + await testOptionChange(0, true, 1, params.disabled_rows_w_not_null, params.result_num_w_not_null); }); await test.step('Deselecting `All records with value` should enable all the values on the list.', async () => { - await RecordsetLocators.getFacetOption(facet, 0).uncheck(); - - // same check as previous 2 tests to make sure displayed options don't change again - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); - - await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(0); - await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(0); + await testOptionChange(0, false, 0, 0, 25); }); await test.step('should be able to select other filters on the facet.', async () => { - await RecordsetLocators.getFacetOption(facet, 1).click(); - - // same check as previous 3 tests to make sure displayed options don't change again - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); - - await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(1); - await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(0); + await testOptionChange(1, true, 1, 0, 25); }); await test.step('Selecting `All records with value` in the list, should remove all the checked filters on facet.', async () => { - await RecordsetLocators.getFacetOption(facet, 0).check(); - - // same check as previous 4 tests to make sure displayed options don't change again - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(testParams.not_null.options_w_not_null); - - await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(1); - await expect.soft(RecordsetLocators.getDisabledFacetOptions(facet)).toHaveCount(testParams.not_null.disabled_rows_w_not_null); + await testOptionChange(0, true, 1, params.disabled_rows_w_not_null, 25); }); }); @@ -490,32 +454,19 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); await test.step('null should be provided as an option and user should be able to select it.', async () => { const params = testParams.null_filter.panel; const facet = RecordsetLocators.getFacetById(page, params.facetIdx); + + await openFacet(page, facet, params.facetIdx, params.totalNumOptions, 4); - await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); - // wait for facet checkboxes to load - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.totalNumOptions); - - await RecordsetLocators.getFacetOption(facet, params.option).click(); - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); - + await testSelectFacetOption(page, facet, params.option, params.numRows, 1); // clear the selected facet - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); await test.step('regarding facets that require right join', async () => { @@ -523,33 +474,17 @@ test.describe('Other facet features', () => { await test.step('null should be provided as an option and user should be able to select it.', async () => { const facet = RecordsetLocators.getFacetById(page, params.firstFacet.idx); - await RecordsetLocators.getFacetHeaderButtonById(facet, params.firstFacet.idx).click(); - - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); - // wait for facet checkboxes to load - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.firstFacet.totalNumOptions); - - await RecordsetLocators.getFacetOption(facet, params.firstFacet.option).check(); - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.firstFacet.numRows); + await openFacet(page, facet, params.firstFacet.idx, params.firstFacet.totalNumOptions, 5); + await testSelectFacetOption(page, facet, params.firstFacet.option, params.firstFacet.numRows, 1); }); await test.step('after selecting one, other such facets should not provide null option.', async () => { const facet = RecordsetLocators.getFacetById(page, params.secondFacet.idx); - await openFacetAndTestFilterOptions( - page, - facet, - params.secondFacet.idx, - params.secondFacet.options, - 6 // 6 open facets - ); + await openFacetAndTestFilterOptions(page, facet, params.secondFacet.idx, params.secondFacet.options, 6); }); }); }); - /*********************************************************** local test cases ***********************************************************/ - // if (process.env.CI) return; - // NOTE the following test cases will only run locally. - test('regarding the logic to show only certain number of selected items', async ({ page, baseURL }, testInfo) => { const params = testParams.hide_selected_items; const facet1 = RecordsetLocators.getFacetById(page, params.firstFacet.index); @@ -697,11 +632,7 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); await test.step('should hide the total count when hide_row_count=true', async () => { @@ -710,10 +641,7 @@ test.describe('Other facet features', () => { const modal = ModalLocators.getRecordsetSearchPopup(page); // facet is already open so we don't have to click to open - await RecordsetLocators.getShowMore(facet).click(); - await RecordsetLocators.waitForRecordsetPageReady(modal); - - await expect.soft(RecordsetLocators.getFirstColumn(modal)).toHaveCount(params.numModalOptions); + await testShowMoreClick(page, facet, modal, params.numModalOptions, 0); await expect.soft(RecordsetLocators.getTotalCount(modal)).toHaveText(params.displayingText); await ModalLocators.getCloseBtn(modal).click(); @@ -725,13 +653,9 @@ test.describe('Other facet features', () => { const modal = ModalLocators.getRecordsetSearchPopup(page); // open the facet first and then open the modal - await RecordsetLocators.getFacetHeaderButtonById(facet, params.facetIdx).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); + await openFacet(page, facet, params.facetIdx, 11, 4); - await RecordsetLocators.getShowMore(facet).click(); - await RecordsetLocators.waitForRecordsetPageReady(modal); - - await expect.soft(RecordsetLocators.getFirstColumn(modal)).toHaveCount(params.numModalOptions); + await testShowMoreClick(page, facet, modal, params.numModalOptions, 0); await expect.soft(RecordsetLocators.getTotalCount(modal)).toHaveText(params.displayingText); await ModalLocators.getCloseBtn(modal).click(); @@ -762,13 +686,7 @@ test.describe('Other facet features', () => { // main await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); - await RecordsetLocators.getFacetHeaderButtonById(facet, params.facet).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); - - // wait for facet checkboxes to load - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.totalNumOptions); - // wait for list to be fully visible - await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); + await openFacet(page, facet, params.facet, params.totalNumOptions, 2); /** * NOTE: this was getFacetOptionsText in protractor because for some reason the .getText started returning empty @@ -779,13 +697,7 @@ test.describe('Other facet features', () => { await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.options); // select a new facet - await RecordsetLocators.getFacetOption(facet, params.option).check(); - - // wait for table rows to load - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRowsWFacet); - - // make sure filter is there - await expect.soft(RecordsetLocators.getFacetFilters(page)).toHaveCount(2); + await testSelectFacetOption(page, facet, params.option, params.numRowsWFacet, 2); }); await test.step('clicking on `x` for Custom Filter should only clear the filter.', async () => { @@ -824,11 +736,7 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); const facet1 = RecordsetLocators.getFacetById(page, 0); await RecordsetLocators.getFacetHeaderButtonById(facet1, 0).click(); @@ -854,11 +762,9 @@ test.describe('Other facet features', () => { const modalSubmit = ModalLocators.getSubmitButton(modal); await test.step('open the facet then open the show more modal', async () => { - await RecordsetLocators.getFacetHeaderButtonById(facet1, params.facetIdx).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet1)).toBeVisible(); + await openFacet(page, facet1, params.facetIdx, 11, 4); - await RecordsetLocators.getShowMore(facet1).click(); - await RecordsetLocators.waitForRecordsetPageReady(modal); + await testShowMoreClick(page, facet1, modal, 25, 0) }); await test.step('after opening the modal, the existing url limit alert should be removed.', async () => { @@ -917,11 +823,7 @@ test.describe('Other facet features', () => { await page.goto(`${baseURL}${PAGE_URL}`); await RecordsetLocators.waitForRecordsetPageReady(page); - const clearAll = RecordsetLocators.getClearAllFilters(page); - await clearAll.click(); - await expect.soft(clearAll).not.toBeVisible(); - - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(25); + await testClearAllFilters(page, 25); }); await test.step('clicking bulk edit should show the same number of forms in RE as rows in RS.', async () => { @@ -964,7 +866,6 @@ test.describe('Other facet features', () => { await expect.soft(RecordsetLocators.getShowFilterPanelBtn(modal)).toBeVisible(); }); - // NOTE: identical to a test below await test.step('clicking the side panel button should open the facet panel', async () => { await RecordsetLocators.getShowFilterPanelBtn(modal).click(); @@ -976,9 +877,7 @@ test.describe('Other facet features', () => { await test.step('select a facet option and select a row for the input', async () => { const facet = RecordsetLocators.getFacetById(modal, 0); - await RecordsetLocators.getFacetOption(facet, 0).click(); - - await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(1); + await testSelectFacetOption(modal, facet, 0, 1, 1); await expect.soft(RecordsetLocators.getFacetFilters(modal).nth(0)).toHaveText(testParams.foreignKeyPopupFacetFilter); const selectButtons = RecordsetLocators.getRows(modal).locator('.select-action-button'); @@ -1024,7 +923,6 @@ test.describe('Other facet features', () => { await expect.soft(RecordsetLocators.getShowFilterPanelBtn(modal)).toBeVisible(); }); - // NOTE: identical to a test above await test.step('clicking the side panel button should open the facet panel', async () => { await RecordsetLocators.getShowFilterPanelBtn(modal).click(); @@ -1036,9 +934,7 @@ test.describe('Other facet features', () => { await test.step('select a facet option and select a row to associate', async () => { const facet = RecordsetLocators.getFacetById(modal, 0); - await RecordsetLocators.getFacetOption(facet, 0).click(); - - await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(1); + await testSelectFacetOption(modal, facet, 0, 1, 1); await expect.soft(RecordsetLocators.getFacetFilters(modal).nth(0)).toHaveText(testParams.associationPopupFacetFilter); await RecordsetLocators.getCheckboxInputs(modal).check(); @@ -1058,7 +954,6 @@ test.describe('Other facet features', () => { const PAGE_URL = `/recordset/#${getCatalogID(testInfo.project.name)}/${testParams.schema_name}:${testParams.table_name}`; await page.goto(`${baseURL}${PAGE_URL}/*::cfacets::${params.cfacetBlob}`); - await page.pause(); await RecordsetLocators.waitForRecordsetPageReady(page); }); @@ -1073,27 +968,9 @@ test.describe('Other facet features', () => { await test.step('main and faceting data should be based on the filter, and be able to apply new filters.', async () => { await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRows); - await RecordsetLocators.getFacetHeaderButtonById(facet, params.facet).click(); - await expect.soft(RecordsetLocators.getFacetCollapse(facet)).toBeVisible(); - - // wait for facet checkboxes to load - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveCount(params.totalNumOptions); - // wait for list to be fully visible - await expect.soft(RecordsetLocators.getList(facet)).toBeVisible(); - - /** - * NOTE: this was getFacetOptionsText in protractor because for some reason the .getText started returning empty - * value for the rows that are hidden because of the height logic - * - * This doesn't seem to be an issue anymore but leaving this comment in case this fails randomly later - */ - await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.options); - - await RecordsetLocators.getFacetOption(facet, params.option).check(); - // wait for table rows to load - await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(params.numRowsWFacet); - // make sure filter is there - await expect.soft(RecordsetLocators.getFacetFilters(page)).toHaveCount(2); + await openFacetAndTestFilterOptions(page, facet, params.facet, params.options, 2); + + await testSelectFacetOption(page, facet, params.option, params.numRowsWFacet, 2); }); await test.step('clicking on `x` for Custom Filter should only clear the filter.', async () => { diff --git a/test/e2e/utils/recordset-utils.ts b/test/e2e/utils/recordset-utils.ts index cd3cb50b5..466edf56c 100644 --- a/test/e2e/utils/recordset-utils.ts +++ b/test/e2e/utils/recordset-utils.ts @@ -74,7 +74,7 @@ export async function openFacetAndTestFilterOptions(page: Page, facet: Locator, * @param numRows number of recordset rows after clicking facet option * @param numFilters number of recordset filters after clicking facet option */ -export async function testSelectFacetOption(page: Page, facet: Locator, optionIdx: number, numRows: number, numFilters: number) { +export async function testSelectFacetOption(page: Page | Locator, facet: Locator, optionIdx: number, numRows: number, numFilters: number) { // open facets show a spinner in the header when the rows are being fetched and is hidden when code execution is finished await expect.soft(RecordsetLocators.getFacetSpinner(facet)).not.toBeVisible(); await RecordsetLocators.getFacetOption(facet, optionIdx).check(); @@ -90,12 +90,40 @@ export async function testSelectFacetOption(page: Page, facet: Locator, optionId * @param optionIdx facet option index to check is unchecked * @param pageSize the recordset page size for comparing with after clear */ -export async function testClearAllFilters(page: Page, facet: Locator, optionIdx: number, pageSize: number) { +export async function testClearAllFilters(page: Page, pageSize: number, facet?: Locator, optionIdx?: number) { const clearAll = RecordsetLocators.getClearAllFilters(page); await clearAll.click(); await expect.soft(clearAll).not.toBeVisible(); - await expect.soft(RecordsetLocators.getFacetOption(facet, optionIdx)).not.toBeChecked(); await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(pageSize); + + if (facet && optionIdx) await expect.soft(RecordsetLocators.getFacetOption(facet, optionIdx)).not.toBeChecked(); +} + +export async function testShowMoreClick(page: Page, facet: Locator, modal: Locator, numRows: number, numCheckedRows: number) { + await RecordsetLocators.getShowMore(facet).click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + await expect.soft(RecordsetLocators.getRows(modal)).toHaveCount(numRows); + await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(numCheckedRows); +} + +export async function testColumnSort(modal: Locator, rawColumnName: string, expectedColumnValues: string[]) { + const sortBtn = RecordsetLocators.getColumnSortButton(modal, rawColumnName); + await expect.soft(sortBtn).toBeVisible(); + + await sortBtn.click(); + await RecordsetLocators.waitForRecordsetPageReady(modal); + + const columnValues = RecordsetLocators.getFirstColumn(modal); + await expect.soft(columnValues).toHaveCount(expectedColumnValues.length); + await expect.soft(columnValues).toHaveText(expectedColumnValues); +} + +export async function testSubmitModalSelection(page: Page, facet: Locator, submitBtn: Locator, numRows: number, numCheckedFacetOptions: number) { + await submitBtn.click(); + + await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(numRows); + await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(numCheckedFacetOptions); } /** @@ -116,7 +144,7 @@ export async function testSelectFacetOptionThenClear(page: Page, facetIdx: numbe await expect.soft(RecordsetLocators.getFacetFilters(page).nth(0)).toHaveText(filterName); - await testClearAllFilters(page, facet, filterIdx, pageSize); + await testClearAllFilters(page, pageSize, facet, filterIdx); }; /** @@ -192,7 +220,7 @@ export async function testRangeInputSubmitThenClear(page: Page, facet: Locator, const optionsCount = await RecordsetLocators.getFacetOptions(facet).count(); // get last item in range inputs list to test it's unchecked - await testClearAllFilters(page, facet, optionsCount - 1, pageSize); + await testClearAllFilters(page, pageSize, facet, optionsCount - 1); } /** @@ -210,7 +238,7 @@ const testInputValue = async (isFloat: boolean, input: Locator, expectedVal: str val = parseFloat(val).toFixed(2); } - await expect.soft(val).toEqual(expectedVal); + expect.soft(val).toEqual(expectedVal); } /** @@ -232,13 +260,13 @@ export async function testRangePickerInputsAfterZoom(rangeInputs: DefaultRangeIn * @param max object with date and time expected values for max inputs */ export async function testTimestampRangePickerInputsAfterZoom( - rangeInputs: TimestampRangeInputLocators, - min: {date: string, time: string}, - max: {date: string, time: string} + rangeInputs: TimestampRangeInputLocators, + min: { date: string, time: string }, + max: { date: string, time: string } ) { await testInputValue(false, rangeInputs.minDateInput, min.date); await testInputValue(false, rangeInputs.maxDateInput, max.date); - + await testInputValue(false, rangeInputs.minTimeInput, min.time); await testInputValue(false, rangeInputs.maxTimeInput, max.time); } From d4dd9d16a512d9612e230b3e82344cadd6fb6ffe Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Mon, 1 Jul 2024 11:02:18 -0700 Subject: [PATCH 07/12] fix rows test when facet option 1 selecetd --- .../specs/delete-prohibited/recordset/misc-facet.spec.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index d2be76a9d..6b4bba7d8 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -418,11 +418,14 @@ test.describe('Other facet features', () => { const testOptionChange = async (optionIdx: number, isCheck: boolean, numCheckedOptions: number, numDisabledOptions: number, numRows: number) => { if (isCheck) { await RecordsetLocators.getFacetOption(facet, optionIdx).check(); + + await expect.soft(RecordsetLocators.getClearAllFilters(page)).toBeVisible(); } else { await RecordsetLocators.getFacetOption(facet, optionIdx).uncheck(); + + await expect.soft(RecordsetLocators.getClearAllFilters(page)).not.toBeVisible(); } - // don't need to be params since it's the same in all tests await expect.soft(RecordsetLocators.getFacetOptions(facet)).toHaveText(params.options_w_not_null); await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(numCheckedOptions); @@ -439,7 +442,7 @@ test.describe('Other facet features', () => { }); await test.step('should be able to select other filters on the facet.', async () => { - await testOptionChange(1, true, 1, 0, 25); + await testOptionChange(1, true, 1, 0, 5); }); await test.step('Selecting `All records with value` in the list, should remove all the checked filters on facet.', async () => { From e203d39f315ebaa4a2d41329a5d65d5cf89ae385 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Mon, 1 Jul 2024 17:02:17 -0700 Subject: [PATCH 08/12] remove misc-facet.spec.js and config file. remove delete proghibitted protractor config and update makefile --- Makefile | 5 +- .../delete-prohibited/protractor.conf.js | 16 - .../recordset/ind-facet.conf.js | 15 - .../recordset/misc-facet.spec.js | 1543 ----------------- 4 files changed, 1 insertion(+), 1578 deletions(-) delete mode 100644 test/e2e/specs/delete-prohibited/protractor.conf.js delete mode 100644 test/e2e/specs/delete-prohibited/recordset/ind-facet.conf.js delete mode 100644 test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.js diff --git a/Makefile b/Makefile index 51ce5743c..8785ca79a 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,6 @@ E2EDrecordLinks=test/e2e/specs/default-config/record/links.config.ts E2EDrecordset=test/e2e/specs/all-features-confirmation/recordset/presentation.conf.js E2EDrecordsetEdit=test/e2e/specs/default-config/recordset/edit.conf.js E2ErecordsetAdd=test/e2e/specs/default-config/recordset/add.conf.js -E2EDrecordsetIndFacetProt=test/e2e/specs/delete-prohibited/recordset/ind-facet.conf.js E2EDrecordsetIndFacet=test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts E2EDrecordsetHistFacet=test/e2e/specs/delete-prohibited/recordset/histogram-facet.config.ts E2ErecordsetSavedQuery=test/e2e/specs/all-features/recordset/saved-query.config.ts @@ -82,7 +81,6 @@ E2Efooter=test/e2e/specs/all-features-confirmation/footer/playwright.config.ts E2Eerrors=test/e2e/specs/all-features-confirmation/errors/errors.config.ts ## Parallel test scripts (protractor) AllFeaturesConfirmationParallel_PROTRACTOR=test/e2e/specs/all-features-confirmation/protractor.conf.js -DeleteProhibitedParallel_PROTRACTOR=test/e2e/specs/delete-prohibited/protractor.conf.js DefaultConfigParallel_PROTRACTOR=test/e2e/specs/default-config/protractor.conf.js ## Parallel test scripts AllFeaturesParallel=test/e2e/specs/all-features/playwright.config.ts @@ -94,11 +92,10 @@ Manualrecordset=test/manual/specs/recordset.conf.js # protractor tests RECORD_TESTS_PROTRACTOR=$(E2EDrecord) -RECORDSET_TESTS_PROTRACTOR=$(E2EDrecordset) $(E2ErecordsetAdd) $(E2EDrecordsetEdit) $(E2EDrecordsetIndFacetProt) +RECORDSET_TESTS_PROTRACTOR=$(E2EDrecordset) $(E2ErecordsetAdd) $(E2EDrecordsetEdit) RECORDADD_TESTS_PROTRACTOR=$(E2EDIrecordAdd) $(E2EDIrecordMultiFormInput) $(E2EDIrecordImmutable) RECORDEDIT_TESTS_PROTRACTOR=$(E2EDIrecordEdit) $(E2EDIrecordMultiEdit) $(E2EDrecordEditSubmissionDisabled) $(E2EDIrecordEditMultiColTypes) DEFAULT_CONFIG_PARALLEL_TESTS_PROTRACTOR=$(DefaultConfigParallel_PROTRACTOR) -DELETE_PROHIBITED_PARALLEL_TESTS_PROTRACTOR=$(DeleteProhibitedParallel_PROTRACTOR) ALL_FEATURES_CONFIRMATION_PARALLEL_TESTS_PROTRACTOR=$(AllFeaturesConfirmationParallel_PROTRACTOR) PARALLEL_TESTS_PROTRACTOR=$(AllFeaturesConfirmationParallel_PROTRACTOR) $(DefaultConfigParallel_PROTRACTOR) $(DeleteProhibitedParallel_PROTRACTOR) ALL_TESTS_PROTRACTOR=$(RECORD_TESTS_PROTRACTOR) $(RECORDSET_TESTS_PROTRACTOR) $(RECORDADD_TESTS_PROTRACTOR) $(RECORDEDIT_TESTS_PROTRACTOR) diff --git a/test/e2e/specs/delete-prohibited/protractor.conf.js b/test/e2e/specs/delete-prohibited/protractor.conf.js deleted file mode 100644 index c8027653e..000000000 --- a/test/e2e/specs/delete-prohibited/protractor.conf.js +++ /dev/null @@ -1,16 +0,0 @@ -var pConfig = require('./../../utils/protractor.configuration.js'); - -var config = pConfig.getConfig({ - // This config is meant to be run as part of the parallel tests configuration - configFileName: 'parallel-configs/delete-prohibited.dev.json', - specs: [ - "*/*.spec.js" - ], - setBaseUrl: function(browser, data) { - browser.params.url = process.env.CHAISE_BASE_URL; - return browser.params.url; - }, - chaiseConfigFilePath: 'test/e2e/specs/delete-prohibited/chaise-config.js' -}); - -exports.config = config; diff --git a/test/e2e/specs/delete-prohibited/recordset/ind-facet.conf.js b/test/e2e/specs/delete-prohibited/recordset/ind-facet.conf.js deleted file mode 100644 index b4d6f9396..000000000 --- a/test/e2e/specs/delete-prohibited/recordset/ind-facet.conf.js +++ /dev/null @@ -1,15 +0,0 @@ -var pConfig = require('./../../../utils/protractor.configuration.js'); - -var config = pConfig.getConfig({ - configFileName: 'recordset/ind-facet.dev.json', - chaiseConfigFilePath: 'test/e2e/specs/delete-prohibited/chaise-config.js', - specs: [ - "misc-facet.spec.js" - ], - setBaseUrl: function(browser, data) { - browser.params.url = process.env.CHAISE_BASE_URL; - return browser.params.url; - } -}); - -exports.config = config; diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.js b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.js deleted file mode 100644 index cf9ca2a01..000000000 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.js +++ /dev/null @@ -1,1543 +0,0 @@ -var chaisePage = require('../../../utils/chaise.page.js'); -var recordEditHelpers = require('../../../utils/recordedit-helpers.js'); -var recordSetHelpers = require('../../../utils/recordset-helpers.js'); -var chance = require('chance').Chance(); -var EC = protractor.ExpectedConditions; - -var testParams = { - schema_name: "faceting", - table_name: "main", - filter_secondary_key: { - facetIdx: 14, - option: 0, - selectedModalOption: 0, - newModalOption: 2, - totalNumOptions: 10, - numRows: 10, - numRowsAfterModal: 11, - removingOptionsNumRowsAfterModal: 25 - }, - facet_order: [ - { - title: "facet with order and column_order false for scalar", - facetIdx: 20, - modalOptions: ['01', '02', '03', '04', '05', '06', '07'], - sortable: false, - modalOptionsSortedByNumOfOccurences: ['07', '06', '05', '04', '03', '02', '01'], - columnName: "col_w_column_order_false" - }, - { - title: "facet without order and hide_num_occurrences true", - facetIdx: 21, - modalOptions: ['01', '13', '12', '11', '10', '09', '08', '07', '06', '05', '04', '03', '02'], - sortable: true, - modalOptionsSortedByScalar: ['13', '12', '11', '10', '09', '08', '07', '06', '05', '04', '03', '02', '01'], - hideNumOccurrences: true, - columnName: "col_w_column_order" - } - ], - not_null: { - option: 5, - result_num_w_not_null: 25, - modal_available_options: 10, - disabled_rows_w_not_null: 11, - options_w_not_null: [ - 'All records with value', 'No value', 'one', 'Empty', 'two', 'seven', 'eight', 'elevens', 'four', 'six', 'ten', 'three' - ] - }, - null_filter: { - panel: { - facetIdx: 5, - totalNumOptions: 12, - option: 1, - numRows: 5 - }, - right_join: { - firstFacet: { - name: "F3 Entity", - idx: 16, - totalNumOptions: 4, - option: 1, - numRows: 23 - }, - secondFacet: { - name: "F5", - idx:17, - options: ["All records with value", "one"] - } - } - }, - hide_row_count: { - hidden: { - facetIdx: 11, - displayingText: "Displaying all\n13\nrecords", - numModalOptions: 13 - - }, - shown: { - facetIdx: 10, - displayingText: "Displaying all\n12\nof 12 records", - numModalOptions: 12 - } - }, - customFilter: { - ermrestFilter: "id=1;id=2;int_col::geq::20", - ermrestFilterDisplayed: "id=1; id=2; int_col::geq::20", - numRows: 7, - numRowsWFacet: 1, - numRowsWOFilter: 1, - facet: 0, - totalNumOptions: 7, - options: ["1", "2", "6", "7", "8", "9", "10"], - optionsWOFilter: ["2", "1", "3", "4", "5", "6", "7", "8", "9", "10"], - option: 1 - }, - customFacet: { - cfacet: { "displayname": "Custom Facet Query", "ermrest_path": "id=1;id=2;id=3;id=14;id=15;id=16;id=17;id=18" }, - cfacetBlob: "N4IgJglgzgDgNgQwJ4DsEFsCmIBcIDCArlAC4D26ABAGIIDGmJlAioZgE5IgA0IH67TKQD6MBCQAWuEBDABeAIwBuWXIBMK+QGZNigCy6FAVkMA2QwHZDADhABfIA", - facet: 10, - totalNumOptions: 3, - option: 1, - numRows: 8, - numRowsWFacet: 3, - numRowsWOCustomFacet: 10, - options: ['No value', 'one', 'two'], - optionsWOCustomFacet: ['No value', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'] - }, - maximumLength: { - facetIdx: 22, - numRows: 25, - filteredNumRows: 24, - secondFacetIdx: 6, - secondFacetOption: 7, - secondFacetNumOptions: 10, - option: 1 - }, - recordColumns: [ "text_col", "longtext_col", "markdown_col", "int_col", "float_col", "date_col", "timestamp_col", "boolean_col", "jsonb_col", "1-o7Ye2EkulrWcCVFNHi3A", "hmZyP_Ufo3E5v_nmdTXyyA" ], - recordValues: { - text_col: "one", - longtext_col: "lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc scelerisque vitae nisl tempus blandit. Nam at tellus sit amet ex consequat euismod. Aenean placerat dui a imperdiet dignissim. Fusce non nulla sed lectus interdum consequat. Praesent vehicula odio ut mauris posuere semper sit amet vitae enim. Vivamus faucibus quam in felis commodo eleifend. Nunc varius sit amet est eget euismod.", - markdown_col: "one", - int_col: "11", - float_col: "11.1100", - date_col: "2001-01-01", - timestamp_col: "2001-01-01 00:01:01", - boolean_col: "true", - jsonb_col: JSON.stringify({"key":"one"},undefined,2), - "1-o7Ye2EkulrWcCVFNHi3A": "one", // faceting_main_fk1 - "hmZyP_Ufo3E5v_nmdTXyyA": "one" // faceting_main_fk2 - }, - shared_path_prefix: { - facetObject: { - "and": [ - {"sourcekey": "outbound_to_f1", "choices": [1, 2, 3, 4, 5, 6]}, - {"sourcekey": "outbound_to_f1_to_outbound1", "choices": [3, 4]} - ] - }, - facetBlob: [ - "N4IghgdgJiBcDaoDOB7ArgJwMYFMDWOAnnCOgC4BG60A+mSjQGYCMIANCFgBYoCWuSOPGZsATGwDMbACxsArGwBsAXQC+bZOmz4iJclTS16TZnQb7qUVh258BQqdLVqgA" - ].join(""), - numRows: 2, - firstFacet: { - index: 10, - options: ["No value", "one", "two", "three", "four", "five", "six"], - modalOptions: ["three", "four"] - }, - secondFacet: { - index: 19, - options: ["three (o1)", "four (o1)", "one (o1)", "six (o1)"], - modalOptions: ["1", "3", "4", "6"] - } - }, - unsupported_filters_error: { - facetObject: { - "and": [ - // will be ignored because of invalid sourcekey name - { - "sourcekey": "some_invalid_key", - "markdown_name": "Facet 1", - "choices": ["1", "2"] - }, - // will be ignored because it's ending in f4 table not f5: - { - "sourcekey": "path_to_f4_scalar_w_id", - "markdown_name": "from_name", - "source_domain": { - "schema": "faceting", - "table": "f5" - }, - "choices": ["3", "4"] - }, - // partially will be ignored - { - "sourcekey": "outbound_to_f1", - "markdown_name": "F1", - "source_domain": { - "schema": "faceting", - "table": "f1", - "column": "term" - }, - "choices": ["one", "missing data", "two", "three", "four", "more missing data"] - } - ] - }, - facetBlob: [ - "N4IghgdgJiBcDaoDOB7ArgJwMYFMDWOAnnCKgLY4D6AlhAG5gA21UlBxANCGWBnlCgDuEShDAUSAMTC4ALg", - "AIAjCC5YAFimq4kceCGVcATCAC6AXw7J02fERIAHMLLWVZKSgDMALJSRYmvJSCNDBcPHwCwqLiOCQeGChk0", - "RJcqJi4lAI8tHDI6jg8cTI4srQA5iogsmAARoyxsCAeAKwgFiDqmtq6IADMlV6mFlbptsSN6LI16NCu7h4G", - "3Lz8QiJiEo2Si2k2mYlgObB5agVgRXLlldV1DU2LWCiMaGQQJLI4GGRtqhpaODoIEAoCCxMLUJBIcryKBOM", - "5cWSCFBXNQYHCgprWSpkFCo+RkcGQiBlaGwobmIA" - ].join(""), - errorTitle: "Unsupported Filters", - errorMessage: [ - "Some (or all) externally supplied filter criteria cannot be implemented with the current catalog content. ", - "This may be due to lack of permissions or changes made to the content since the criteria were initially saved.\n", - "Discarded facets: Facet 1, from_name\n", - "Facets with some discarded choices: F1\n\n\n", - "Click OK to continue with the subset of filter criteria which are supported at this time.", - "\nShow Error Details" - ].join(""), - errorDetails: [ - "Discarded facets:\n\n- Facet 1 (2 choices):\n - 1\n - 2\n- from_name (2 choices):\n - 3\n - 4\n\n\n", - "Partially discarded facets:\n\n- F1 (2/6 choices):\n - missing data\n - more missing data" - ].join(""), - facetBlobAfterOK: [ - "N4IghgdgJiBcDaoDOB7ArgJwMYFM6JHQBcAjdafEAMzFyIEsIBzEAGhAFsxGB9KgawCMIALoBfdvRgj2WABYp6uJPgAsrQawDMrAEzjxQA" - ].join(""), - numRows: 22 - }, - hide_selected_items: { - // not used and only added here so we know what the blob represents - facetObject: { - "and": [ - {"source": "id", "choices": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}, - {"source": "text_col", "choices": ["one", "two"]} - ] - }, - facetBlob: 'N4IghgdgJiBcDaoDOB7ArgJwMYFM4gEsYAaELACxQNyTngEZiAmYgZmIBZiBWYgNmIB2YgA5iATmL0ADFMb0mAXQC+xZOmx5YIAC44AHjoD6WFABsQpClRp0QKCHlI6A7ihAqVQA', - numRows: 10, - firstFacet: { - index: 0, - options: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], - optionsAfterFirstChange: ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11"], - optionsAfterFinalChange: ["4", "5", "6", "7", "8", "9", "10", "11", "12", "1"], - }, - secondFacet: { - index: 5, - selectedOption: 3, - options: ["All records with value", "No value", "one", "two", "four", "three"] - } - }, - hideFilterPanelClass: "chaise-sidebar-close", - showFilterPanelClass: "chaise-sidebar-open", - foreignKeyPopupFacetFilter: "term\neight", - associationRTName: "main_f3_assoc", - associationPopupFacetFilter: "term\nfive", - associationPopupSelectedRowsFilter: "five" -}; - - -describe("Other facet features, ", function() { - - describe("selecting entity facet that is not on the shortest key.", function () { - var facet, idx, clearAll; - beforeAll(function (done) { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - - chaisePage.navigate(uri); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - chaisePage.waitForElement(clearAll); - - idx = testParams.filter_secondary_key.facetIdx; - facet = chaisePage.recordsetPage.getFacetHeaderButtonById(idx); - - chaisePage.clickButton(clearAll).then(function () { - done() - }).catch(chaisePage.catchTestError(done)); - }); - - it('Side panel should hide/show by clicking pull button', function(done){ - var recPan = chaisePage.recordsetPage.getSidePanel(), - showPanelBtn = chaisePage.recordsetPage.getShowFilterPanelBtn(), - hidePanelBtn = chaisePage.recordsetPage.getHideFilterPanelBtn(); - - expect(hidePanelBtn.isDisplayed()).toBeTruthy('hide filter panel not visible.'); - expect(recPan.getAttribute("class")).toContain('open-panel', 'Side Panel is not visible'); - - hidePanelBtn.click().then(function(){ - expect(showPanelBtn.isDisplayed()).toBeTruthy('show filter panel not visible.'); - expect(recPan.getAttribute("class")).toContain('close-panel', 'Side Panel is not hidden'); - - return showPanelBtn.click(); - }).then(function () { - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("should open the facet, select a value to filter on.", function (done) { - chaisePage.clickButton(facet).then(function () { - // wait for facet to open - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); - - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { - return ct == testParams.filter_secondary_key.totalNumOptions; - }); - }, browser.params.defaultTimeout); - - // wait for list to be fully visible - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(idx)), browser.params.defaultTimeout); - - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(idx, testParams.filter_secondary_key.option)); - }).then(function () { - // wait for request to return - browser.wait(EC.visibilityOf(clearAll), browser.params.defaultTimeout); - - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == testParams.filter_secondary_key.numRows; - }); - }, browser.params.defaultTimeout); - - return chaisePage.recordsetPage.getRows().count(); - }).then(function (ct) { - expect(ct).toBe(testParams.filter_secondary_key.numRows, "number of rows is incorrect"); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("the selected value should be selected on the modal.", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getShowMore(idx)).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getModalOptions().count().then(function(ct) { - return ct == 12; - }); - }, browser.params.defaultTimeout); - - expect(chaisePage.recordsetPage.getCheckedModalOptions().count()).toBe(1, "number of checked rows missmatch."); - return chaisePage.recordsetPage.getModalOptions(); - }).then(function (options) { - expect(options[testParams.filter_secondary_key.selectedModalOption].isSelected()).toBeTruthy("the correct option was not selected."); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("selecting new values on the modal and submitting them, should change the filters on submit.", function (done) { - chaisePage.recordsetPage.getModalOptions().then(function (options) { - return chaisePage.clickButton(options[testParams.filter_secondary_key.newModalOption]); - }).then(function () { - expect(chaisePage.recordsetPage.getModalSubmit().getText()).toBe("Submit", "Submit button text for add pure and binary popup is incorrect"); - - return chaisePage.clickButton(chaisePage.recordsetPage.getModalSubmit()); - }).then(function () { - - browser.wait(function() { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return (ct == testParams.filter_secondary_key.numRowsAfterModal); - }); - }, browser.params.defaultTimeout, "number of visible rows after selecting a second option missmatch."); - - browser.wait(function() { - return chaisePage.recordsetPage.getCheckedFacetOptions(idx).count().then(function(ct) { - return (ct == 2); - }); - }, browser.params.defaultTimeout, "Number of facet options is incorrect after returning from modal"); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("removing values in the modal should allow for submitting to remove the set of selected options for that facet.", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getShowMore(idx)).then(function () { - browser.wait(function() { - return chaisePage.recordsetPage.getCheckedModalOptions().count().then(function(ct) { - return (ct == 2); - }); - }, browser.params.defaultTimeout, "number of checked rows mismatch."); - - // clear selections in modal to remove selections in facet - return chaisePage.recordsetPage.getModalClearSelection(chaisePage.searchPopup.getFacetPopup()).click(); - }).then(function () { - expect(chaisePage.recordsetPage.getCheckedModalOptions().count()).toBe(0, "number of checked rows missmatch after clearing selection."); - - return chaisePage.clickButton(chaisePage.recordsetPage.getModalSubmit()); - }).then(function () { - browser.wait(function() { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return (ct == testParams.filter_secondary_key.removingOptionsNumRowsAfterModal); - }); - }, browser.params.defaultTimeout, "number of visible rows after selecting a second option missmatch."); - - browser.wait(function() { - return chaisePage.recordsetPage.getCheckedFacetOptions(idx).count().then(function(ct) { - return (ct == 0); - }); - }, browser.params.defaultTimeout, "Number of facet options is incorrect after returning from modal"); - - //no need to clear all filters, this test removed the last selected facet options - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - }); - - describe("facet modal rows and columns, ", function () { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var clearAll, showMore, sortBtn; - - beforeAll(function (done) { - - // using browser.get with the same uri doesn't work, so we should just refresh - chaisePage.navigate(uri); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - browser.wait(EC.elementToBeClickable(clearAll)); - - clearAll.click().then(function () { - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - testParams.facet_order.forEach(function (params) { - describe("for " + params.title + ", ", function () { - it ("the rows in the modal should honor the given order.", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getFacetHeaderButtonById(params.facetIdx)).then(function () { - // wait for facet to open - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(params.facetIdx)), browser.params.defaultTimeout); - - // click on show more - var showMore = chaisePage.recordsetPage.getShowMore(params.facetIdx); - browser.wait(EC.elementToBeClickable(showMore)); - return chaisePage.clickButton(showMore); - }).then(function () { - chaisePage.recordsetPage.waitForInverseModalSpinner(); - browser.wait(function () { - return chaisePage.recordsetPage.getModalFirstColumn().then(function(values) { - return values.length == params.modalOptions.length; - }); - }, browser.params.defaultTimeout); - - return chaisePage.recordsetPage.getModalFirstColumn(); - }).then(function (values) { - values.forEach(function (val, idx) { - expect(val.getText()).toEqual(params.modalOptions[idx], "modal options missmatch"); - }); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - if (!params.sortable) { - it ("the facet column sort option should not be available.", function () { - expect(chaisePage.recordsetPage.getColumnSortButton("0").isPresent()).toBe(false); - }); - } else { - it ("users should be able to change the sort to be based on the scalar column.", function (done) { - sortBtn = chaisePage.recordsetPage.getColumnSortButton("0"); - expect(sortBtn.isDisplayed()).toBe(true, "sort button is not available."); - chaisePage.clickButton(sortBtn).then(function () { - chaisePage.recordsetPage.waitForInverseModalSpinner(); - - // this will wait for the list to be the same as expected, otherwise will timeout - browser.wait(function () { - return chaisePage.recordsetPage.getModalFirstColumn().getText().then(function (texts) { - return JSON.stringify(texts) === JSON.stringify(params.modalOptionsSortedByScalar); - }).catch(chaisePage.catchTestError(done)); - }, browser.params.defaultTimeout); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - } - - it ("number of Occurrences column should be " + (params.hideNumOccurrences ? "hidden": "available") + ".", function (done) { - chaisePage.recordsetPage.getModalColumnNames().then(function (columns) { - expect(columns.length).toBe(params.hideNumOccurrences ? 1 : 2, "length missmatch"); - expect(columns[0].getText()).toBe(params.columnName, "column name missmatch"); - if (!params.hideNumOccurrences) { - expect(columns[1].getText()).toBe("Number of Occurrences", "num of occ column name missmatch."); - } - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - if (!params.hideNumOccurrences) { - it ("numer of Occurrences column should be available and users should be able to sort based on that.", function (done) { - sortBtn = chaisePage.recordsetPage.getColumnSortButton("count"); - expect(sortBtn.isDisplayed()).toBe(true, "sort button is not available."); - chaisePage.clickButton(sortBtn).then(function () { - chaisePage.recordsetPage.waitForInverseModalSpinner(); - - browser.wait(function () { - return chaisePage.recordsetPage.getModalFirstColumn().then(function(values) { - return values.length == params.modalOptionsSortedByNumOfOccurences.length; - }); - }, browser.params.defaultTimeout); - - browser.sleep(75); - - return chaisePage.recordsetPage.getModalFirstColumn(); - }).then(function (values) { - values.forEach(function (val, idx) { - expect(val.getText()).toEqual(params.modalOptionsSortedByNumOfOccurences[idx], "modal options missmatch"); - }); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - } - - it ('should close the facet modal', function (done) { - chaisePage.recordsetPage.getModalCloseBtn().click().then(function () { - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - }); - - }); - - describe("Records With Value (not-null) filter, ", function () { - var notNullBtn, showMore, facet; - - beforeAll(function (done) { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - browser.wait(EC.elementToBeClickable(clearAll)); - - clearAll.click().then(function () { - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - facet = chaisePage.recordsetPage.getFacetHeaderButtonById(testParams.not_null.option); - - return chaisePage.clickButton(facet); - }).then(function () { - showMore = chaisePage.recordsetPage.getShowMore(testParams.not_null.option); - notNullBtn = chaisePage.recordsetPage.getFacetOption(testParams.not_null.option, 0); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("`All Records with value` option must be available in facet panel.", function (done) { - // make sure facet is loaded - browser.wait(EC.elementToBeClickable(showMore)); - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(testParams.not_null.option).count().then(function(ct) { - return ct == 12; - }); - }, browser.params.defaultTimeout); - - chaisePage.recordsetPage.getFacetOptions(testParams.not_null.option).then(function (opts) { - opts.forEach(function (option, idx) { - expect(option.getText()).toEqual(testParams.not_null.options_w_not_null[idx], "the options are not the same."); - }); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("After clicking on `All records with value`, the rest of options must be disabled", function (done) { - - chaisePage.clickButton(notNullBtn).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getCheckedFacetOptions(testParams.not_null.option).count().then(function(ct) { - return ct == 1; - }); - }, browser.params.defaultTimeout); - - return chaisePage.recordsetPage.getCheckedFacetOptions(testParams.not_null.option).count() - }).then(function (count) { - expect(count).toBe(1, "number of selected filters missmatch."); - - return chaisePage.recordsetPage.getFacetOptions(testParams.not_null.option); - }).then(function (opts) { - opts.forEach(function (option, idx) { - expect(option.getText()).toEqual(testParams.not_null.options_w_not_null[idx], "the text of selected faacet missmatch."); - }); - - expect(chaisePage.recordsetPage.getDisabledFacetOptions(testParams.not_null.option).count()).toBe(testParams.not_null.disabled_rows_w_not_null, "numer of disabled filters missmatch."); - expect(chaisePage.recordsetPage.getRows().count()).toBe(testParams.not_null.result_num_w_not_null, "number of results missmatch."); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("Deselecting `All records with value` should enable all the values on the list.", function (done) { - chaisePage.clickButton(notNullBtn).then(function () { - return chaisePage.recordsetPage.getFacetOptions(testParams.not_null.option); - }).then(function (opts) { - // make sure the options havn't changed - opts.forEach(function (option, idx) { - expect(option.getText()).toEqual(testParams.not_null.options_w_not_null[idx], "the text of selected faacet missmatch."); - }); - - // expect(chaisePage.recordsetPage.getModalMatchNullInput().getAttribute('disabled')).not.toBe('true', "null option is still disabled."); - expect(chaisePage.recordsetPage.getCheckedFacetOptions(testParams.not_null.option).count()).toBe(0, "number of selected filters missmatch."); - expect(chaisePage.recordsetPage.getDisabledFacetOptions(testParams.not_null.option).count()).toBe(0, "numer of disabled filters missmatch."); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("should be able to select other filters on the facet.", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(testParams.not_null.option, 1)).then(function () { - return chaisePage.recordsetPage.getFacetOptions(testParams.not_null.option); - }).then(function (opts) { - // make sure the options havn't changed - opts.forEach(function (option, idx) { - expect(option.getText()).toEqual(testParams.not_null.options_w_not_null[idx], "the text of selected faacet missmatch."); - }); - - expect(chaisePage.recordsetPage.getCheckedFacetOptions(testParams.not_null.option).count()).toBe(1, "Number of selected filters missmatch."); - expect(chaisePage.recordsetPage.getDisabledFacetOptions(testParams.not_null.option).count()).toBe(0, "numer of disabled filters missmatch."); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("Selecting `All records with value` in the list, should remove all the checked filters on facet.", function (done) { - chaisePage.clickButton(notNullBtn).then(function () { - return chaisePage.recordsetPage.getFacetOptions(testParams.not_null.option); - }).then(function (opts) { - // make sure the options haven't changed - opts.forEach(function (option, idx) { - expect(option.getText()).toEqual(testParams.not_null.options_w_not_null[idx], "the text of selected faacet missmatch."); - }); - - expect(chaisePage.recordsetPage.getCheckedFacetOptions(testParams.not_null.option).count()).toBe(1, "number of selected filters missmatch."); - expect(chaisePage.recordsetPage.getDisabledFacetOptions(testParams.not_null.option).count()).toBe(testParams.not_null.disabled_rows_w_not_null, "numer of disabled filters missmatch."); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - describe("No value (null) filter, ", function () { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var clearAll, showMore, nullBtn; - - beforeAll(function (done) { - // using browser.get with the same uri doesn't work, so we should just refresh - chaisePage.navigate(uri) - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - browser.wait(EC.elementToBeClickable(clearAll)); - - clearAll.click().then(function () { - chaisePage.waitForElementInverse(element(by.id("spinner"))); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("null should be provided as an option and user should be able to select it.", function (done) { - var params = testParams.null_filter.panel; - chaisePage.recordsetPage.getFacetHeaderButtonById(params.facetIdx).click().then(function () { - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(params.facetIdx).count().then(function(ct) { - return ct == params.totalNumOptions; - }); - }, browser.params.defaultTimeout); - - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(params.facetIdx, params.option)); - }).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == params.numRows; - }); - }, browser.params.defaultTimeout); - - // clear the selected facet - return clearAll.click(); - }).then(function () { - chaisePage.recordsetPage.waitForInverseMainSpinner(); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - describe("regarding facets that require right join, ", function () { - var params = testParams.null_filter.right_join, idx; - it ("null should be provided as an option and user should be able to select it.", function (done) { - idx = params.firstFacet.idx; - chaisePage.recordsetPage.getFacetHeaderButtonById(idx).click().then(function () { - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); - - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { - return ct == params.firstFacet.totalNumOptions; - }); - }, browser.params.defaultTimeout); - - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(idx, params.firstFacet.option)); - }).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == params.firstFacet.numRows; - }); - }, browser.params.defaultTimeout); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("after selecting one, other such facets should not provide null option.", function (done) { - recordSetHelpers.openFacetAndTestFilterOptions( - params.secondFacet.name, params.secondFacet.idx, params.secondFacet.options, done - ); - }); - }); - }); - - /*********************************************************** local test cases ***********************************************************/ - if (process.env.CI) return; - // NOTE the following test cases will only run locally. - - describe('regarding the logic to show only certian number of selected items,', function () { - var uriPrefix = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var currParams = testParams.hide_selected_items; - const facetIdx = currParams.firstFacet.index; - const secondFacetIdx = currParams.secondFacet.index; - - beforeAll(function(done) { - var uri = uriPrefix + "/*::facets::" + currParams.facetBlob; - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - done(); - }); - - it ('facet panel should only show limited number of selected facet options.', function (done) { - // wait for facet to open - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(facetIdx)), browser.params.defaultTimeout); - - // wait for list to be fully visible - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(facetIdx)), browser.params.defaultTimeout); - - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(facetIdx).getText().then(function (opts) { - return JSON.stringify(opts) === JSON.stringify(currParams.firstFacet.options); - }).catch(chaisePage.catchTestError(done)); - }, browser.params.defaultTimeout); - - // make sure all are selected - expect(chaisePage.recordsetPage.getCheckedFacetOptions(0).count()).toBe(currParams.firstFacet.options.length, 'not all options are selected'); - - // make sure the text is visible - expect(chaisePage.recordsetPage.getFacetMoreFiltersText(facetIdx).getText()).toEqual('2 selected items not displayed.'); - - done(); - }); - - it ('interacting with other facet should rearrange the options and update the message.', function (done) { - // deselect the first option in the first facet - chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(facetIdx, 0)).then(() => { - // wait for list to be fully visible - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(secondFacetIdx)), browser.params.defaultTimeout); - - // in the second facet, deselect third option (first two are not-null and null) - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(secondFacetIdx, currParams.secondFacet.selectedOption)); - }).then(() => { - // wait for facet checkboxes to load for the first facet - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(facetIdx).getText().then(function (opts) { - return JSON.stringify(opts) === JSON.stringify(currParams.firstFacet.optionsAfterFirstChange); - }).catch(chaisePage.catchTestError(done)); - }, browser.params.defaultTimeout); - - // make sure all are selected - expect(chaisePage.recordsetPage.getCheckedFacetOptions(0).count()).toBe(currParams.firstFacet.optionsAfterFirstChange.length, 'not all options are selected'); - - // make sure the text is updated - expect(chaisePage.recordsetPage.getFacetMoreFiltersText(facetIdx).getText()).toEqual('1 selected items not displayed.'); - - done(); - }).catch(chaisePage.catchTestError(done)); - - }); - - it ('going below the limit should remove the message.', function (done) { - // deselect first and second options in the first facet so we go below the limit - chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(facetIdx, 0)).then(() => { - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(facetIdx, 1)); - }).then(() => { - // in the second facet, deselect third option (first two are not-null and null) - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(secondFacetIdx, currParams.secondFacet.selectedOption)); - }).then (() => { - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(facetIdx).getText().then(function (opts) { - return JSON.stringify(opts) === JSON.stringify(currParams.firstFacet.optionsAfterFinalChange); - }).catch(chaisePage.catchTestError(done)); - }, browser.params.defaultTimeout); - - // make sure the text has disapeared - expect(chaisePage.recordsetPage.getFacetMoreFiltersText(facetIdx).isDisplayed()).toBeFalsy(); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - describe("regarding facets with shared path,", function () { - var uriPrefix = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var currParams = testParams.shared_path_prefix; - - beforeAll(function(done) { - var uri = uriPrefix + "/*::facets::" + currParams.facetBlob; - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - done(); - }); - - it ("the main results should be correct", function (done) { - // wait for table rows to load - // NOTE 2 rows - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == currParams.numRows; - }); - }, browser.params.defaultTimeout); - - // the wait itself is doing the test - done(); - }); - - describe("for the facet with subset path, ", function () { - recordSetHelpers.testFacetOptions( - currParams.firstFacet.index, - currParams.firstFacet.options, - currParams.firstFacet.modalOptions - ); - }); - - describe("for the facet with superset path, ", function () { - recordSetHelpers.testFacetOptions( - currParams.secondFacet.index, - currParams.secondFacet.options, - currParams.secondFacet.modalOptions - ); - }); - }); - - describe("regarding UnsupportedFilters handling, ", function () { - var uriPrefix = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var currParams = testParams.unsupported_filters_error; - - beforeAll(function() { - var uri = uriPrefix + "/*::facets::" + currParams.facetBlob; - chaisePage.navigate(uri); - chaisePage.waitForElement(element(by.css('.modal-dialog '))); - }); - - it('Proper error should be displayed', function(){ - var modalTitle = chaisePage.errorModal.getTitle(); - expect(modalTitle.getText()).toBe("Unsupported Filters"); - }); - - it('Error modal message must summarize the issue', function(){ - var modalText = chaisePage.errorModal.getBody(); - expect(modalText.getText()).toEqual(currParams.errorMessage, "The message in modal pop is not correct"); - }); - - it('Error modal should Show Error Details', function(done){ - var showDetails = chaisePage.errorModal.getToggleDetailsLink(); - var errorDetails = chaisePage.errorModal.getErrorDetails(); - chaisePage.waitForElement(showDetails); - showDetails.click().then(function(){ - chaisePage.waitForElement(errorDetails); - expect(showDetails.getText()).toBe("Hide Error Details", "The Show/Hide message in modal pop is not correct"); - expect(errorDetails.getText()).toEqual(currParams.errorDetails, "error missmatch."); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it('On click of OK button the page should dismiss the error and show proper results', function(done){ - const modalOkBtn = chaisePage.errorModal.getOKButton(); - browser.wait(protractor.ExpectedConditions.elementToBeClickable(modalOkBtn), browser.params.defaultTimeout); - chaisePage.clickButton(modalOkBtn).then (function (){ - // make sure it's showing proper number of values - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == currParams.numRows; - }); - }, browser.params.defaultTimeout); - - return browser.driver.getCurrentUrl(); - }).then (function(currentUrl) { - - var newURL = uriPrefix + "/*::facets::" + currParams.facetBlobAfterOK; - expect(currentUrl).toContain(newURL, "The redirection from record page to recordset in case of multiple records failed"); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - }); - - describe("regarding hide_row_count support in entity facet popups", function () { - beforeAll(function (done) { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element.all(by.id("spinner")).first()); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - chaisePage.waitForElement(clearAll); - chaisePage.clickButton(clearAll).then(function () { - done() - }).catch(chaisePage.catchTestError(done)); - }); - - it ("should hide the total count when hide_row_count=true", function (done) { - // facet is already open so we don't have to click to open - var facetParams = testParams.hide_row_count.hidden; - var showMore = chaisePage.recordsetPage.getShowMore(facetParams.facetIdx); - browser.wait(EC.elementToBeClickable(showMore)); - chaisePage.clickButton(showMore).then(function () { - chaisePage.recordsetPage.waitForInverseModalSpinner(); - browser.wait(function () { - return chaisePage.recordsetPage.getModalFirstColumn().then(function(values) { - return values.length == facetParams.numModalOptions; - }); - }, browser.params.defaultTimeout); - - expect(chaisePage.recordsetPage.getModalTotalCount(chaisePage.searchPopup.getFacetPopup()).getText()).toBe(facetParams.displayingText, "hide_row_count not honored"); - - return chaisePage.recordsetPage.getModalCloseBtn().click(); - }).then(function (){ - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("otherwise should show the total count", function (done) { - var facetParams = testParams.hide_row_count.shown; - var facet = chaisePage.recordsetPage.getFacetHeaderButtonById(facetParams.facetIdx); - - // open the facet first and then open the modal - chaisePage.clickButton(facet).then(function () { - var showMore = chaisePage.recordsetPage.getShowMore(facetParams.facetIdx); - browser.wait(EC.elementToBeClickable(showMore)); - return chaisePage.clickButton(showMore) - }).then(function () { - chaisePage.recordsetPage.waitForInverseModalSpinner(); - browser.wait(function () { - return chaisePage.recordsetPage.getModalFirstColumn().then(function(values) { - return values.length == facetParams.numModalOptions; - }); - }, browser.params.defaultTimeout); - - expect(chaisePage.recordsetPage.getModalTotalCount(chaisePage.searchPopup.getFacetPopup()).getText()).toBe(facetParams.displayingText, "hide_row_count not honored"); - - return chaisePage.recordsetPage.getModalCloseBtn().click(); - }).then(function (){ - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - }); - - describe("navigating to recordset with filters that faceting doesn't support.", function () { - var customFilterParams = testParams.customFilter; - var idx = customFilterParams.facet; - - beforeAll(function () { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - - uri += "/" + customFilterParams.ermrestFilter; - - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - }); - - it ("should show the applied filter and clear all button.", function (done) { - browser.wait(function () { - return chaisePage.recordsetPage.getFacetFilters().count().then(function(ct) { - return ct == 1; - }); - }, browser.params.defaultTimeout); - - chaisePage.recordsetPage.getFacetFilters().then(function (filters) { - expect(filters.length).toEqual(1, "filter is missing"); - - expect(filters[0].getText()).toEqual("Custom Filter\n" + customFilterParams.ermrestFilterDisplayed, "filter text missmatch."); - - expect(chaisePage.recordsetPage.getClearAllFilters().isDisplayed()).toBeTruthy("`Clear All` is not visible"); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("main and faceting data should be based on the filter, and be able to apply new filters.", function (done) { - // main - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == customFilterParams.numRows; - }); - }, browser.params.defaultTimeout); - expect(chaisePage.recordsetPage.getRows().count()).toEqual(customFilterParams.numRows, "total row count missmatch."); - - chaisePage.clickButton(chaisePage.recordsetPage.getFacetHeaderButtonById(idx)).then(function () { - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); - - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { - return ct == customFilterParams.totalNumOptions; - }); - }, browser.params.defaultTimeout); - - // wait for list to be fully visible - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(idx)), browser.params.defaultTimeout); - - /** - * NOTE: this used to be getFacetOptions, but for some reason the .getText started returning empty - * value for the rows that are hidden because of the height logic - * so I changed it to directly get the text from javascript. - */ - return chaisePage.recordsetPage.getFacetOptionsText(idx); - }).then(function (opts) { - opts.forEach(function (option, i) { - expect(option).toEqual(customFilterParams.options[i], `options missmatch, index=${i}`); - }); - - // select a new facet - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(idx, customFilterParams.option)); - }).then(function () { - // wait for table rows to load - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == customFilterParams.numRowsWFacet; - }); - }, browser.params.defaultTimeout); - - // make sure data has been updated - expect(chaisePage.recordsetPage.getRows().count()).toBe(customFilterParams.numRowsWFacet, ""); - - // make sure filter is there - expect(chaisePage.recordsetPage.getFacetFilters().count()).toBe(2, "facet filter missing."); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("clicking on `x` for Custom Filter should only clear the filter.", function (done) { - expect(chaisePage.recordsetPage.getClearCustomFilters().isDisplayed()).toBeTruthy("`Clear Custom Filters` is not visible."); - - chaisePage.clickButton(chaisePage.recordsetPage.getClearCustomFilters()).then(function () { - chaisePage.waitForElementInverse(element(by.id("spinner"))); - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == customFilterParams.numRowsWOFilter; - }); - }, browser.params.defaultTimeout); - - expect(chaisePage.recordsetPage.getRows().count()).toEqual(customFilterParams.numRowsWOFilter, "total row count missmatch."); - - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { - return ct == customFilterParams.optionsWOFilter.length; - }); - }, browser.params.defaultTimeout); - - /** - * NOTE: this used to be getFacetOptions, but for some reason the .getText started returning empty - * value for the rows that are hidden because of the height logic - * so I changed it to directly get the text from javascript. - */ - return chaisePage.recordsetPage.getFacetOptionsText(idx); - }).then(function (opts) { - opts.forEach(function (option, i) { - expect(option).toEqual(customFilterParams.optionsWOFilter[i], `options missmatch, index=${i}`); - }); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - describe("regarding URL limitation check, ", function () { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var clearAll; - var alert = chaisePage.recordsetPage.getWarningAlert(); - var submitBtn = chaisePage.recordsetPage.getModalSubmit(); - var idx = testParams.maximumLength.facetIdx; - var facet = chaisePage.recordsetPage.getFacetHeaderButtonById(idx); - - var checkAlert = function (al) { - browser.wait(EC.visibilityOf(al, browser.params.defaultTimeout)); - expect(al.getText()).toContain("WarningMaximum URL length reached. Cannot perform the requested action.", "alert message missmatch."); - }; - - beforeAll(function (done) { - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - browser.wait(EC.elementToBeClickable(clearAll)); - - //close the first facet - chaisePage.recordsetPage.getFacetHeaderButtonById(0).click().then(function () { - //close the second facet - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetHeaderButtonById(1)); - }).then(function () { - return clearAll.click(); - }).then(function () { - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("searching a lenghty string should show the `Maximum URL length reached` warning.", function () { - var mainSearch = chaisePage.recordsetPage.getMainSearchInput(); - mainSearch.sendKeys(chance.string({length: 4000})); - chaisePage.recordsetPage.waitForInverseMainSpinner(); - expect(chaisePage.recordsetPage.getRows().count()).toBe(testParams.maximumLength.numRows, "row count missmatch."); - checkAlert(alert); - }); - - /** - * The following test only works for ermrest installation that have - * `quantified_value_lists` feature. - */ - describe("in facet modal, ", function () { - var modalAlert = chaisePage.recordsetPage.getModalWarningAlert(chaisePage.searchPopup.getFacetPopup()); - beforeAll(function (done) { - chaisePage.clickButton(facet).then(function () { - // wait for facet to open - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); - - // click on show more - var showMore = chaisePage.recordsetPage.getShowMore(idx); - browser.wait(EC.elementToBeClickable(showMore)); - return chaisePage.clickButton(showMore); - }).then(function () { - chaisePage.waitForElementInverse(element.all(by.id("spinner")).first()); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ('after opening the modal, the existing url limit alert should be removed.', function () { - expect(modalAlert.isPresent()).toBeFalsy(); - }); - - it ("alert should be displayed upon reaching the URL limit and submit button should be disabled.", function (done) { - browser.wait(function () { - return chaisePage.recordsetPage.getModalRows().count().then(function (ct) { - return (ct == 25); - }); - }); - - chaisePage.clickButton(chaisePage.recordsetPage.getSelectAllBtn()).then(function () { - checkAlert(modalAlert); - expect(submitBtn.getAttribute('disabled')).toBe('true', "submit is not disabled."); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("changing filters and going below the URL limit should hide the alert and enable the submit button.", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getModalRecordsetTableOptionByIndex(chaisePage.searchPopup.getFacetPopup(), 0)).then(function () { - chaisePage.waitForElementInverse(alert); - expect(submitBtn.getAttribute('disabled')).not.toBe('true', "submit is disabled."); - return chaisePage.clickButton(submitBtn); - }).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == testParams.maximumLength.filteredNumRows; - }); - }, browser.params.defaultTimeout); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - /** - * The following test only works for ermrest installation that have - * `quantified_value_lists` feature. - */ - describe("in main container, ", function () { - var secondFacetIdx = testParams.maximumLength.secondFacetIdx; - - it ("alert should be displayed upon reaching the URL limit and the request should not be completed.", function (done) { - var secondFacet = chaisePage.recordsetPage.getFacetHeaderButtonById(secondFacetIdx); - - var secondFacetOption = chaisePage.recordsetPage.getFacetOption( - secondFacetIdx, - testParams.maximumLength.secondFacetOption - ); - - chaisePage.clickButton(secondFacet).then(function () { - // wait for facet to open - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(secondFacetIdx)), browser.params.defaultTimeout); - - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(secondFacetIdx).count().then(function(ct) { - return ct == testParams.maximumLength.secondFacetNumOptions; - }); - }, browser.params.defaultTimeout); - - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(secondFacetIdx)), browser.params.defaultTimeout); - - return secondFacetOption.click(); - }).then(function () { - checkAlert(alert); - expect(secondFacetOption.isSelected()).toBeFalsy("the option is checked."); - done(); - }).catch(chaisePage.catchTestError(done)); - - }); - - it ("changing filters and going below the URL limit should hide the alert.", function (done) { - var facetOption = chaisePage.recordsetPage.getFacetOption( - idx, - testParams.maximumLength.option - ); - - chaisePage.clickButton(facetOption).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == testParams.maximumLength.filteredNumRows - 1; - }); - }, browser.params.defaultTimeout); - expect(alert.isPresent()).toBeFalsy("alert is visible"); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - }); - - describe("navigating to record and recordedit app with facets.", function () { - - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - var clearAll; - - describe("from recordset app with multiple records", function () { - - beforeAll(function (done) { - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - clearAll = chaisePage.recordsetPage.getClearAllFilters(); - browser.wait(EC.elementToBeClickable(clearAll)); - - clearAll.click().then(function () { - chaisePage.waitForElementInverse(element(by.id("spinner"))); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("clicking edit should show the same number of forms in RE as rows in RS.", function (done) { - var editLink = chaisePage.recordsetPage.getEditRecordLink(); - browser.wait(EC.elementToBeClickable(editLink)); - - editLink.click().then(function() { - browser.wait(function() { - return chaisePage.recordEditPage.getRecordeditForms().count().then(function(ct) { - return (ct == 25); - }); - }, browser.params.defaultTimeout); - - return chaisePage.recordEditPage.getRecordeditForms().count(); - }).then(function(count) { - expect(count).toBe(25); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - describe("in recordedit app, foreign key popup should have facets available,", function() { - - var hidePanelBtn, showPanelBtn, sidePanel, modalBody; - - beforeAll(function (done) { - chaisePage.navigate(uri); - - chaisePage.waitForUrl('facets', browser.params.defaultTimeout); - - browser.getCurrentUrl().then(function (url) { - var uri = url.replace("recordset", "recordedit"); - chaisePage.navigate(uri); - - chaisePage.recordeditPageReady(); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("should click the foreign key popup button and have the facet collapse button visible in search popup", function (done) { - expect(chaisePage.recordEditPage.getRecordeditForms().count()).toBe(1, "number of forms shown is incorrect"); - chaisePage.recordEditPage.getModalPopupBtns().then(function(popupBtns) { - // open the first fk popup - return chaisePage.clickButton(popupBtns[0]); - }).then(function () { - browser.wait(EC.visibilityOf(chaisePage.recordEditPage.getModalTitle()), browser.params.defaultTimeout); - - browser.wait(function () { - return chaisePage.recordsetPage.getModalRows().count().then(function (ct) { - return (ct == 13); - }); - }); - - modalBody = element(by.css('.modal-body')); - - // make sure side bar is hidden - sidePanel = chaisePage.recordsetPage.getSidePanel(modalBody); - expect(sidePanel.isDisplayed()).toBe(false); - - // get show filter panel - showPanelBtn = chaisePage.recordsetPage.getShowFilterPanelBtn(modalBody); - chaisePage.waitForElement(showPanelBtn); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("clicking the side panel button should open the facet panel", function (done) { - showPanelBtn.click().then(function () { - browser.wait(EC.visibilityOf(sidePanel), browser.params.defaultTimeout); - - hidePanelBtn = chaisePage.recordsetPage.getHideFilterPanelBtn(modalBody); - chaisePage.waitForElement(hidePanelBtn); - - expect(sidePanel.isDisplayed()).toBeTruthy("Side panel is not visible after opening it"); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("select a facet option and select a row for the input", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(0, 0)).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getModalRows().count().then(function (ct) { - return (ct == 1); - }); - }); - - return chaisePage.recordsetPage.getFacetFilters(); - }).then(function (filters) { - expect(filters[0].getText()).toBe(testParams.foreignKeyPopupFacetFilter, "Filter for facet is incorrect"); - - return chaisePage.recordsetPage.getModalRows().get(0).all(by.css(".select-action-button")); - }).then(function (selectButtons) { - expect(selectButtons.length).toBe(1, "number of selectable rows is incorrect"); - - return selectButtons[0].click(); - }).then(function () { - browser.wait(EC.visibilityOf(chaisePage.recordEditPage.getEntityTitleElement()), browser.params.defaultTimeout); - - var foreignKeyInputDisplay = chaisePage.recordEditPage.getForeignKeyInputDisplay("fk_to_f1", 0); - expect(foreignKeyInputDisplay.getText()).toEqual("eight", "Didn't select the expected foreign key."); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - - describe("in record app, association add popup should have facets available,", function() { - - var hidePanelBtn, showPanelBtn, sidePanel, modalBody; - - beforeAll(function (done) { - chaisePage.navigate(uri); - chaisePage.waitForUrl('facets', browser.params.defaultTimeout); - - browser.getCurrentUrl().then(function (url) { - var uri = url.replace("recordset", "record"); - chaisePage.navigate(uri); - - chaisePage.waitForElement(element(by.css('.record-main-section-table'))); - done(); - }).catch(chaisePage.catchTestError(done)); - }) - - it("navigating to record with a facet url", function () { - recordEditHelpers.testRecordAppValuesAfterSubmission(testParams.recordColumns, testParams.recordValues, testParams.recordColumns.length); - }); - - it("should click the add button for an association table and have the facet collapse button visible", function (done) { - chaisePage.recordPage.getAddRecordLink(testParams.associationRTName).click().then(function () { - browser.wait(EC.visibilityOf(chaisePage.recordEditPage.getModalTitle()), browser.params.defaultTimeout); - - browser.wait(function () { - return chaisePage.recordsetPage.getModalRows().count().then(function (ct) { - return (ct == 5); - }); - }); - - modalBody = element(by.css('.modal-body')); - - // make sure side bar is hidden - sidePanel = chaisePage.recordsetPage.getSidePanel(modalBody); - expect(sidePanel.isDisplayed()).toBe(false); - - // get show filter panel - showPanelBtn = chaisePage.recordsetPage.getShowFilterPanelBtn(modalBody); - chaisePage.waitForElement(showPanelBtn); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("clicking the side panel button should open the facet panel", function (done) { - showPanelBtn.click().then(function () { - browser.wait(EC.visibilityOf(sidePanel), browser.params.defaultTimeout); - - hidePanelBtn = chaisePage.recordsetPage.getHideFilterPanelBtn(modalBody); - chaisePage.waitForElement(hidePanelBtn); - - expect(sidePanel.isDisplayed()).toBeTruthy("Side panel is not visible after opening it"); - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it("select a facet option and select a row to associate", function (done) { - chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(0, 0)).then(function () { - browser.wait(function () { - return chaisePage.recordsetPage.getRecordsetTableModalOptions().count().then(function (ct) { - return (ct == 1); - }); - }); - - return chaisePage.recordsetPage.getFacetFilters(); - }).then(function (filters) { - expect(filters[0].getText()).toBe(testParams.associationPopupFacetFilter, "Filter for selected rows is incorrect"); - - var rowCheckbox = chaisePage.recordsetPage.getModalRecordsetTableOptionByIndex(chaisePage.searchPopup.getAddPureBinaryPopup(), 0); - - return chaisePage.clickButton(rowCheckbox); - }).then(function () { - //verify selected row filter - return chaisePage.recordsetPage.getSelectedRowsFilters(); - }).then(function (filters) { - expect(filters[0].getText()).toBe(testParams.associationPopupSelectedRowsFilter, "Filter for facet is incorrect"); - // NOTE: we don't test add here because we aren't trying to test mutating data, but whether the popup behaves appropriately with faceting - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); - }); - - describe("navigating to recordset with custom facet.", function () { - var customFacetParams = testParams.customFacet; - var idx = customFacetParams.facet; - - beforeAll(function () { - var uri = browser.params.url + "/recordset/#" + browser.params.catalogId + "/" + testParams.schema_name + ":" + testParams.table_name; - - uri += "/*::cfacets::" + customFacetParams.cfacetBlob; - - chaisePage.navigate(uri); - chaisePage.waitForElementInverse(element(by.id("spinner"))); - }); - - it ("should show the applied filter and clear all button.", function (done) { - browser.wait(function () { - return chaisePage.recordsetPage.getFacetFilters().count().then(function(ct) { - return ct == 1; - }); - }, browser.params.defaultTimeout); - - chaisePage.recordsetPage.getFacetFilters().then(function (filters) { - expect(filters[0].getText()).toEqual("Custom Filter\n" + customFacetParams.cfacet.displayname, "filter text missmatch."); - - expect(chaisePage.recordsetPage.getClearAllFilters().isDisplayed()).toBeTruthy("`Clear All` is not visible"); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("main and faceting data should be based on the filter, and be able to apply new filters.", function (done) { - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == customFacetParams.numRows; - }); - }, browser.params.defaultTimeout); - // main - expect(chaisePage.recordsetPage.getRows().count()).toEqual(customFacetParams.numRows, "total row count missmatch."); - - chaisePage.clickButton(chaisePage.recordsetPage.getFacetHeaderButtonById(idx)).then(function () { - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getFacetCollapse(idx)), browser.params.defaultTimeout); - - // wait for facet checkboxes to load - browser.wait(function () { - return chaisePage.recordsetPage.getFacetOptions(idx).count().then(function(ct) { - return ct == customFacetParams.totalNumOptions; - }); - }, browser.params.defaultTimeout); - - // wait for list to be fully visible - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(idx)), browser.params.defaultTimeout); - - /** - * NOTE: this used to be getFacetOptions, but for some reason the .getText started returning empty - * value for the rows that are hidden because of the height logic - * so I changed it to directly get the text from javascript. - */ - return chaisePage.recordsetPage.getFacetOptionsText(idx); - }).then(function (opts) { - opts.forEach(function (option, i) { - expect(option).toEqual(customFacetParams.options[i], `options missmatch, index=${i}`); - }); - - // select a new facet - return chaisePage.clickButton(chaisePage.recordsetPage.getFacetOption(idx, customFacetParams.option)); - }).then(function () { - // wait for table rows to load - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == customFacetParams.numRowsWFacet; - }); - }, browser.params.defaultTimeout); - - // make sure data has been updated - expect(chaisePage.recordsetPage.getRows().count()).toBe(customFacetParams.numRowsWFacet, ""); - - // make sure filter is there - expect(chaisePage.recordsetPage.getFacetFilters().count()).toBe(2, "facet filter missing."); - - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - - it ("clicking on `x` for Custom Filter should only clear the filter.", function (done) { - expect(chaisePage.recordsetPage.getClearCustomFacets().isDisplayed()).toBeTruthy("`Clear Custom Facets` is not visible."); - - chaisePage.recordsetPage.getClearCustomFacets().click().then(function () { - // wait for table rows to load - browser.wait(function () { - return chaisePage.recordsetPage.getRows().count().then(function(ct) { - return ct == customFacetParams.numRowsWOCustomFacet; - }); - }, browser.params.defaultTimeout); - - expect(chaisePage.recordsetPage.getRows().count()).toEqual(customFacetParams.numRowsWOCustomFacet, "total row count missmatch."); - - // wait for list to be fully visible - browser.wait(EC.visibilityOf(chaisePage.recordsetPage.getList(idx)), browser.params.defaultTimeout); - - /** - * NOTE: this used to be getFacetOptions, but for some reason the .getText started returning empty - * value for the rows that are hidden because of the height logic - * so I changed it to directly get the text from javascript. - */ - return chaisePage.recordsetPage.getFacetOptionsText(idx); - }).then(function (opts) { - opts.forEach(function (option, i) { - expect(option).toEqual(customFacetParams.optionsWOCustomFacet[i], `options missmatch, index=${i}`); - }); - - done(); - }).catch(chaisePage.catchTestError(done)); - }); - }); -}); From 87c9d21eef02f164716d320a6ed07a9545256e69 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Mon, 1 Jul 2024 17:03:48 -0700 Subject: [PATCH 09/12] uncommitted change and update e2e.yml --- .github/workflows/e2e.yml | 9 --------- Makefile | 5 +---- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 235f0dafc..2fcf682cc 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -179,12 +179,6 @@ jobs: run: | cd chaise make testdefaultconfig-protractor - - name: Run delete prohibited test spec (protractor) - id: test-protractor-delete-prohibited - continue-on-error: true - run: | - cd chaise - make testdeleteprohibited-protractor - name: Check on all features test spec if: always() && steps.test-all-features.outcome != 'success' run: exit 1 @@ -203,9 +197,6 @@ jobs: - name: Check on default config test spec (protractor) if: always() && steps.test-protractor-default-config.outcome != 'success' run: exit 1 - - name: Check on delete prohibited test spec (protractor) - if: always() && steps.test-protractor-delete-prohibited.outcome != 'success' - run: exit 1 - uses: actions/upload-artifact@v4 if: always() with: diff --git a/Makefile b/Makefile index 8785ca79a..8b8402020 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ RECORDADD_TESTS_PROTRACTOR=$(E2EDIrecordAdd) $(E2EDIrecordMultiFormInput) $(E2ED RECORDEDIT_TESTS_PROTRACTOR=$(E2EDIrecordEdit) $(E2EDIrecordMultiEdit) $(E2EDrecordEditSubmissionDisabled) $(E2EDIrecordEditMultiColTypes) DEFAULT_CONFIG_PARALLEL_TESTS_PROTRACTOR=$(DefaultConfigParallel_PROTRACTOR) ALL_FEATURES_CONFIRMATION_PARALLEL_TESTS_PROTRACTOR=$(AllFeaturesConfirmationParallel_PROTRACTOR) -PARALLEL_TESTS_PROTRACTOR=$(AllFeaturesConfirmationParallel_PROTRACTOR) $(DefaultConfigParallel_PROTRACTOR) $(DeleteProhibitedParallel_PROTRACTOR) +PARALLEL_TESTS_PROTRACTOR=$(AllFeaturesConfirmationParallel_PROTRACTOR) $(DefaultConfigParallel_PROTRACTOR) ALL_TESTS_PROTRACTOR=$(RECORD_TESTS_PROTRACTOR) $(RECORDSET_TESTS_PROTRACTOR) $(RECORDADD_TESTS_PROTRACTOR) $(RECORDEDIT_TESTS_PROTRACTOR) # playwright tests @@ -211,9 +211,6 @@ testallfeaturesconfirmation-protractor: test_protractor-ALL_FEATURES_CONFIRMATIO .PHONY: testdeleteprohibited testdeleteprohibited: test-DELETE_PROHIBITED_PARALLEL_TESTS -.PHONY: testdeleteprohibited-protractor -testdeleteprohibited-protractor: test_protractor-DELETE_PROHIBITED_PARALLEL_TESTS_PROTRACTOR - #Rule to run the default chaise configuration tests in parallel .PHONY: testdefaultconfig testdefaultconfig: test-DEFAULT_CONFIG_PARALLEL_TESTS From 7e55d457ba79a344534025455cc24c0c2628b247 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Wed, 3 Jul 2024 17:40:31 -0700 Subject: [PATCH 10/12] rename ind-facet files to facet since it's general now. add comments to functions, wait for modal to not be attached --- ...nd-facet.config.json => facet.config.json} | 0 .../{ind-facet.dev.json => facet.dev.json} | 2 +- .../{ind-facet.config.ts => facet.config.ts} | 6 ++-- ...facet.spec.ts => individual-facet.spec.ts} | 0 .../recordset/misc-facet.spec.ts | 27 ++++++++--------- test/e2e/utils/recordset-utils.ts | 30 +++++++++++++++++-- 6 files changed, 44 insertions(+), 21 deletions(-) rename test/e2e/data_setup/config/recordset/{ind-facet.config.json => facet.config.json} (100%) rename test/e2e/data_setup/config/recordset/{ind-facet.dev.json => facet.dev.json} (72%) rename test/e2e/specs/delete-prohibited/recordset/{ind-facet.config.ts => facet.config.ts} (67%) rename test/e2e/specs/delete-prohibited/recordset/{ind-facet.spec.ts => individual-facet.spec.ts} (100%) diff --git a/test/e2e/data_setup/config/recordset/ind-facet.config.json b/test/e2e/data_setup/config/recordset/facet.config.json similarity index 100% rename from test/e2e/data_setup/config/recordset/ind-facet.config.json rename to test/e2e/data_setup/config/recordset/facet.config.json diff --git a/test/e2e/data_setup/config/recordset/ind-facet.dev.json b/test/e2e/data_setup/config/recordset/facet.dev.json similarity index 72% rename from test/e2e/data_setup/config/recordset/ind-facet.dev.json rename to test/e2e/data_setup/config/recordset/facet.dev.json index 8d4f685a1..cf4d48aa3 100644 --- a/test/e2e/data_setup/config/recordset/ind-facet.dev.json +++ b/test/e2e/data_setup/config/recordset/facet.dev.json @@ -1,7 +1,7 @@ { "setup": { "schemaConfigurations": [ - "recordset/ind-facet.config.json" + "recordset/facet.config.json" ], "schema": "faceting" }, diff --git a/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts b/test/e2e/specs/delete-prohibited/recordset/facet.config.ts similarity index 67% rename from test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts rename to test/e2e/specs/delete-prohibited/recordset/facet.config.ts index 5ddb8d6c4..f051f1c31 100644 --- a/test/e2e/specs/delete-prohibited/recordset/ind-facet.config.ts +++ b/test/e2e/specs/delete-prohibited/recordset/facet.config.ts @@ -1,12 +1,12 @@ import getConfig from '@isrd-isi-edu/chaise/test/e2e/setup/playwright.configuration'; export default getConfig({ - testName: 'delete-prohibited/recordset/ind-facet', - configFileName: 'recordset/ind-facet.dev.json', + testName: 'delete-prohibited/recordset/facet', + configFileName: 'recordset/facet.dev.json', mainSpecName: 'delete-prohibited', testMatch: [ 'facet-presentation.spec.ts', - 'ind-facet.spec.ts', + 'individual-facet.spec.ts', 'four-facet-selections.spec.ts', 'misc-facet.spec.ts' ] diff --git a/test/e2e/specs/delete-prohibited/recordset/ind-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/individual-facet.spec.ts similarity index 100% rename from test/e2e/specs/delete-prohibited/recordset/ind-facet.spec.ts rename to test/e2e/specs/delete-prohibited/recordset/individual-facet.spec.ts diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index 6b4bba7d8..4ae8f1a39 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -12,8 +12,8 @@ import RecordsetLocators from '@isrd-isi-edu/chaise/test/e2e/locators/recordset' import { getCatalogID } from '@isrd-isi-edu/chaise/test/e2e/utils/catalog-utils'; import { testRecordMainSectionValues } from '@isrd-isi-edu/chaise/test/e2e/utils/record-utils'; import { - openFacet, openFacetAndTestFilterOptions, - testColumnSort, testClearAllFilters, testFacetOptions, + openFacet, openFacetAndTestFilterOptions, testColumnSort, + testClearAllFilters, testFacetOptions, testModalClose, testSelectFacetOption, testShowMoreClick, testSubmitModalSelection } from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; @@ -308,7 +308,7 @@ test.describe('Other facet features', () => { }); await test.step('the selected value should be selected in the modal.', async () => { - await testShowMoreClick(page, facet, modal, 12, 1); + await testShowMoreClick(facet, modal, 12, 1); await expect.soft(RecordsetLocators.getCheckboxInputs(modal).nth(testParams.filter_secondary_key.selectedModalOption)).toBeChecked(); }); @@ -318,18 +318,17 @@ test.describe('Other facet features', () => { const submit = ModalLocators.getSubmitButton(modal); await expect.soft(submit).toHaveText('Submit'); - await testSubmitModalSelection(page, facet, submit, testParams.filter_secondary_key.numRowsAfterModal, 2); + await testSubmitModalSelection(page, facet, modal, testParams.filter_secondary_key.numRowsAfterModal, 2); }); await test.step('removing values in the modal should allow for submitting to remove the set of selected options for that facet.', async () => { - await testShowMoreClick(page, facet, modal, 12, 2); + await testShowMoreClick(facet, modal, 12, 2); // clear selections in modal to remove selections in facet await RecordsetLocators.getClearSelectedRows(modal).click(); await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(0); - const submit = ModalLocators.getSubmitButton(modal); - await testSubmitModalSelection(page, facet, submit, testParams.filter_secondary_key.removingOptionsNumRowsAfterModal, 0); + await testSubmitModalSelection(page, facet, modal, testParams.filter_secondary_key.removingOptionsNumRowsAfterModal, 0); }); }); @@ -351,7 +350,7 @@ test.describe('Other facet features', () => { await openFacet(page, facet, params.facetIdx, params.numFacetOptions, params.numOpenFacets); // click on show more - await testShowMoreClick(page, facet, modal, params.modalOptions.length, 0); + await testShowMoreClick(facet, modal, params.modalOptions.length, 0); const columnValues = RecordsetLocators.getFirstColumn(modal); await expect.soft(columnValues).toHaveCount(params.modalOptions.length); @@ -387,7 +386,7 @@ test.describe('Other facet features', () => { } await test.step('should close the facet modal', async () => { - await ModalLocators.getCloseBtn(modal).click(); + await testModalClose(modal); }); } }); @@ -644,10 +643,10 @@ test.describe('Other facet features', () => { const modal = ModalLocators.getRecordsetSearchPopup(page); // facet is already open so we don't have to click to open - await testShowMoreClick(page, facet, modal, params.numModalOptions, 0); + await testShowMoreClick(facet, modal, params.numModalOptions, 0); await expect.soft(RecordsetLocators.getTotalCount(modal)).toHaveText(params.displayingText); - await ModalLocators.getCloseBtn(modal).click(); + await testModalClose(modal); }); await test.step('otherwise should show the total count', async () => { @@ -658,10 +657,10 @@ test.describe('Other facet features', () => { // open the facet first and then open the modal await openFacet(page, facet, params.facetIdx, 11, 4); - await testShowMoreClick(page, facet, modal, params.numModalOptions, 0); + await testShowMoreClick(facet, modal, params.numModalOptions, 0); await expect.soft(RecordsetLocators.getTotalCount(modal)).toHaveText(params.displayingText); - await ModalLocators.getCloseBtn(modal).click(); + await testModalClose(modal); }); }); @@ -767,7 +766,7 @@ test.describe('Other facet features', () => { await test.step('open the facet then open the show more modal', async () => { await openFacet(page, facet1, params.facetIdx, 11, 4); - await testShowMoreClick(page, facet1, modal, 25, 0) + await testShowMoreClick(facet1, modal, 25, 0) }); await test.step('after opening the modal, the existing url limit alert should be removed.', async () => { diff --git a/test/e2e/utils/recordset-utils.ts b/test/e2e/utils/recordset-utils.ts index 466edf56c..80dc91448 100644 --- a/test/e2e/utils/recordset-utils.ts +++ b/test/e2e/utils/recordset-utils.ts @@ -99,7 +99,12 @@ export async function testClearAllFilters(page: Page, pageSize: number, facet?: if (facet && optionIdx) await expect.soft(RecordsetLocators.getFacetOption(facet, optionIdx)).not.toBeChecked(); } -export async function testShowMoreClick(page: Page, facet: Locator, modal: Locator, numRows: number, numCheckedRows: number) { +/** + * clicks show more button and makes sure modal has finished loading + * @param numRows number of recordset rows in modal on load + * @param numCheckedRows number of checked rows in modal on load + */ +export async function testShowMoreClick(facet: Locator, modal: Locator, numRows: number, numCheckedRows: number) { await RecordsetLocators.getShowMore(facet).click(); await RecordsetLocators.waitForRecordsetPageReady(modal); @@ -107,6 +112,19 @@ export async function testShowMoreClick(page: Page, facet: Locator, modal: Locat await expect.soft(RecordsetLocators.getCheckedCheckboxInputs(modal)).toHaveCount(numCheckedRows); } +/** + * close the modal and make sure it's not attached anymore + */ +export async function testModalClose(modal: Locator) { + await ModalLocators.getCloseBtn(modal).click(); + await expect.soft(modal).not.toBeAttached(); +} + +/** + * sort a column and make sure the values are as expected for the first column in the modal + * @param rawColumnName raw name of column we are sorting by + * @param expectedColumnValues all of the values for the first column in the table after sorted + */ export async function testColumnSort(modal: Locator, rawColumnName: string, expectedColumnValues: string[]) { const sortBtn = RecordsetLocators.getColumnSortButton(modal, rawColumnName); await expect.soft(sortBtn).toBeVisible(); @@ -119,8 +137,14 @@ export async function testColumnSort(modal: Locator, rawColumnName: string, expe await expect.soft(columnValues).toHaveText(expectedColumnValues); } -export async function testSubmitModalSelection(page: Page, facet: Locator, submitBtn: Locator, numRows: number, numCheckedFacetOptions: number) { - await submitBtn.click(); +/** + * submit the modal selections and make the recordset + * @param numRows number of recordset rows after submitting modal selection + * @param numCheckedFacetOptions number of checked facet options for `facet` after submitting modal selection + */ +export async function testSubmitModalSelection(page: Page, facet: Locator, modal: Locator, numRows: number, numCheckedFacetOptions: number) { + await ModalLocators.getSubmitButton(modal).click(); + await expect.soft(modal).not.toBeAttached(); await expect.soft(RecordsetLocators.getRows(page)).toHaveCount(numRows); await expect.soft(RecordsetLocators.getCheckedFacetOptions(facet)).toHaveCount(numCheckedFacetOptions); From cd2896f0d8a1b8a2a4bec974f8936d8a1e6c9ecd Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Wed, 3 Jul 2024 18:18:04 -0700 Subject: [PATCH 11/12] more comments and change function name --- .../specs/delete-prohibited/recordset/misc-facet.spec.ts | 6 +++--- test/e2e/utils/recordset-utils.ts | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts index 4ae8f1a39..e8671b049 100644 --- a/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts +++ b/test/e2e/specs/delete-prohibited/recordset/misc-facet.spec.ts @@ -13,7 +13,7 @@ import { getCatalogID } from '@isrd-isi-edu/chaise/test/e2e/utils/catalog-utils' import { testRecordMainSectionValues } from '@isrd-isi-edu/chaise/test/e2e/utils/record-utils'; import { openFacet, openFacetAndTestFilterOptions, testColumnSort, - testClearAllFilters, testFacetOptions, testModalClose, + testClearAllFilters, testFacetOptionsAndModalRows, testModalClose, testSelectFacetOption, testShowMoreClick, testSubmitModalSelection } from '@isrd-isi-edu/chaise/test/e2e/utils/recordset-utils'; @@ -566,7 +566,7 @@ test.describe('Other facet features', () => { }); await test.step('for the facet with subset path', async () => { - await testFacetOptions( + await testFacetOptionsAndModalRows( page, params.firstFacet.index, params.firstFacet.options, @@ -575,7 +575,7 @@ test.describe('Other facet features', () => { }); await test.step('for the facet with superset path', async () => { - await testFacetOptions( + await testFacetOptionsAndModalRows( page, params.secondFacet.index, params.secondFacet.options, diff --git a/test/e2e/utils/recordset-utils.ts b/test/e2e/utils/recordset-utils.ts index 80dc91448..c16750cf9 100644 --- a/test/e2e/utils/recordset-utils.ts +++ b/test/e2e/utils/recordset-utils.ts @@ -335,7 +335,13 @@ export async function openRecordsetAndResetFacetState( }); } -export async function testFacetOptions(page: Page, facetIdx: number, filterOptions: string[], modalOptions: string[]) { +/** + * test facet options and and first column values in show more modal + * @param facetIdx index of the facet we are testing + * @param filterOptions all of the values of facet options in facet + * @param modalOptions all of the values for the first column in the modal table + */ +export async function testFacetOptionsAndModalRows(page: Page, facetIdx: number, filterOptions: string[], modalOptions: string[]) { const facet = RecordsetLocators.getFacetById(page, facetIdx); await test.step('the facet options should be correct', async () => { @@ -358,5 +364,6 @@ export async function testFacetOptions(page: Page, facetIdx: number, filterOptio await expect.soft(RecordsetLocators.getFirstColumn(modal)).toHaveText(modalOptions); await ModalLocators.getCloseBtn(modal).click(); + await expect.soft(modal).not.toBeAttached(); }); } \ No newline at end of file From aa8d5d005888084fcb1f1daf952d6aae2d1b5b94 Mon Sep 17 00:00:00 2001 From: Joshua Chudy Date: Wed, 3 Jul 2024 18:19:08 -0700 Subject: [PATCH 12/12] missed file path change --- .../config/parallel-configs/delete-prohibited.dev.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/data_setup/config/parallel-configs/delete-prohibited.dev.json b/test/e2e/data_setup/config/parallel-configs/delete-prohibited.dev.json index 1d70d3702..bfce07f2c 100644 --- a/test/e2e/data_setup/config/parallel-configs/delete-prohibited.dev.json +++ b/test/e2e/data_setup/config/parallel-configs/delete-prohibited.dev.json @@ -4,7 +4,7 @@ "navbar/catalog-chaise-config.config.json", "record/config.json", "recordedit/delete.config.json", - "recordset/ind-facet.config.json", + "recordset/facet.config.json", "recordset/histogram-facet.config.json" ] },