From 3916c76c554f43cd3a89a0376f8f6d51f4610a40 Mon Sep 17 00:00:00 2001 From: Jen Jones Arnesen Date: Wed, 24 Feb 2021 12:11:21 +0100 Subject: [PATCH 1/4] fix: render a separate filterbadge for small screen --- src/components/FilterBar/FilterBadge.js | 59 ++++++++++--------- .../FilterBar/__tests__/FilterBadge.spec.js | 44 ++++++++++++++ .../__snapshots__/FilterBadge.spec.js.snap | 51 ++++++++++++++++ .../FilterBar/styles/FilterBadge.module.css | 16 +++++ 4 files changed, 143 insertions(+), 27 deletions(-) create mode 100644 src/components/FilterBar/__tests__/FilterBadge.spec.js create mode 100644 src/components/FilterBar/__tests__/__snapshots__/FilterBadge.spec.js.snap diff --git a/src/components/FilterBar/FilterBadge.js b/src/components/FilterBar/FilterBadge.js index 3ff28de66..20570f264 100644 --- a/src/components/FilterBar/FilterBadge.js +++ b/src/components/FilterBar/FilterBadge.js @@ -8,33 +8,38 @@ import { acSetActiveModalDimension } from '../../actions/activeModalDimension' import classes from './styles/FilterBadge.module.css' -const FilterBadge = ({ filter, openFilterModal, removeFilter }) => ( -
- - openFilterModal({ - id: filter.id, - name: filter.name, - }) - } - > - {`${filter.name}: ${ - filter.values.length > 1 - ? i18n.t('{{count}} selected', { - count: filter.values.length, - }) - : filter.values[0].name - }`} - - removeFilter(filter.id)} - > - {i18n.t('Remove')} - -
-) +const FilterBadge = ({ filter, openFilterModal, removeFilter }) => { + const filterText = `${filter.name}: ${ + filter.values.length > 1 + ? i18n.t('{{count}} selected', { + count: filter.values.length, + }) + : filter.values[0].name + }` + + return ( +
+ + openFilterModal({ + id: filter.id, + name: filter.name, + }) + } + > + {filterText} + + {filterText} + removeFilter(filter.id)} + > + {i18n.t('Remove')} + +
+ ) +} FilterBadge.propTypes = { filter: PropTypes.object.isRequired, diff --git a/src/components/FilterBar/__tests__/FilterBadge.spec.js b/src/components/FilterBar/__tests__/FilterBadge.spec.js new file mode 100644 index 000000000..83c37ca9e --- /dev/null +++ b/src/components/FilterBar/__tests__/FilterBadge.spec.js @@ -0,0 +1,44 @@ +import React from 'react' +import { render } from '@testing-library/react' +import { Provider } from 'react-redux' +import configureMockStore from 'redux-mock-store' +import FilterBadge from '../FilterBadge' + +const mockStore = configureMockStore() + +test('Filter Badge displays badge containing number of items in filter', () => { + const filter = { + id: 'ponies', + name: 'Ponies', + values: [{ name: 'Rainbow Dash' }, { name: 'Twilight Sparkle' }], + } + const { container } = render( + + + + ) + expect(container).toMatchSnapshot() +}) + +test('FilterBadge displays badge with filter item name when only one filter item', () => { + const filter = { + id: 'ponies', + name: 'Ponies', + values: [{ name: 'Twilight Sparkle' }], + } + + const { container } = render( + + + + ) + expect(container).toMatchSnapshot() +}) diff --git a/src/components/FilterBar/__tests__/__snapshots__/FilterBadge.spec.js.snap b/src/components/FilterBar/__tests__/__snapshots__/FilterBadge.spec.js.snap new file mode 100644 index 000000000..1ab71fa19 --- /dev/null +++ b/src/components/FilterBar/__tests__/__snapshots__/FilterBadge.spec.js.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Filter Badge displays badge containing number of items in filter 1`] = ` +
+
+ + Ponies: 2 selected + + + Ponies: 2 selected + + + Remove + +
+
+`; + +exports[`FilterBadge displays badge with filter item name when only one filter item 1`] = ` +
+
+ + Ponies: Twilight Sparkle + + + Ponies: Twilight Sparkle + + + Remove + +
+
+`; diff --git a/src/components/FilterBar/styles/FilterBadge.module.css b/src/components/FilterBar/styles/FilterBadge.module.css index 138153e0c..f4f898c4a 100644 --- a/src/components/FilterBar/styles/FilterBadge.module.css +++ b/src/components/FilterBar/styles/FilterBadge.module.css @@ -15,9 +15,25 @@ white-space: nowrap; } +.badgeSmall { + display: none; + font-size: 13px; + white-space: nowrap; +} + .removeButton { font-size: 12px; text-decoration: underline; margin-left: var(--spacers-dp24); cursor: pointer; } + +@media only screen and (max-width: 480px) { + .badge { + display: none; + } + + .badgeSmall { + display: block; + } +} From 14fc53408d77317cc403cd088b53deb7beedf498 Mon Sep 17 00:00:00 2001 From: Jen Jones Arnesen Date: Wed, 24 Feb 2021 13:13:33 +0100 Subject: [PATCH 2/4] fix: add cypress test for both large and small screen --- cypress/integration/common/add_filter.js | 44 +++++++++++++++++++ .../integration/ui/dashboard_filter.feature | 6 +++ .../ui/dashboard_filter/dashboard_filter.js | 34 +++----------- .../ui/responsive_dashboard.feature | 8 ++++ .../responsive_dashboard.js | 5 +++ cypress/selectors/dashboardFilter.js | 6 ++- src/components/ItemFilter/FilterDialog.js | 2 +- 7 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 cypress/integration/common/add_filter.js diff --git a/cypress/integration/common/add_filter.js b/cypress/integration/common/add_filter.js new file mode 100644 index 000000000..48684424b --- /dev/null +++ b/cypress/integration/common/add_filter.js @@ -0,0 +1,44 @@ +import { When } from 'cypress-cucumber-preprocessor/steps' +import { + filterBadgeSel, + unselectedItemsSel, + filterDimensionsPanelSel, + dimensionsModalSel, + orgUnitCheckboxesSel, +} from '../../selectors/dashboardFilter' +import { EXTENDED_TIMEOUT } from '../../support/utils' + +const PERIOD = 'Last 6 months' +const OU = 'Sierra Leone' +const FACILITY_TYPE = 'Clinic' + +When('I add a {string} filter', dimensionType => { + cy.contains('Add filter').click() + + // open the dimensions modal + cy.get(filterDimensionsPanelSel).contains(dimensionType).click() + + // select an item in the modal + if (dimensionType === 'Period') { + cy.get(unselectedItemsSel).contains(PERIOD).dblclick() + } else if (dimensionType === 'Organisation Unit') { + cy.get(dimensionsModalSel, EXTENDED_TIMEOUT).find('.arrow').click() + cy.get(dimensionsModalSel, EXTENDED_TIMEOUT) + .find(orgUnitCheckboxesSel, EXTENDED_TIMEOUT) + .contains(OU, EXTENDED_TIMEOUT) + .click() + } else { + cy.get(unselectedItemsSel).contains(FACILITY_TYPE).dblclick() + } + + // confirm to apply the filter + cy.get('button').contains('Confirm').click() +}) + +When('I click on the {string} filter badge', filterName => { + cy.get(filterBadgeSel) + .find('span') + .not('.badgeSmall') + .contains(filterName) + .click() +}) diff --git a/cypress/integration/ui/dashboard_filter.feature b/cypress/integration/ui/dashboard_filter.feature index 1cd977b52..24191a3e5 100644 --- a/cypress/integration/ui/dashboard_filter.feature +++ b/cypress/integration/ui/dashboard_filter.feature @@ -18,3 +18,9 @@ Feature: Dashboard filter Scenario: I add a Facility Type filter When I add a "Facility Type" filter Then the Facility Type filter is applied to the dashboard + + @nonmutating + Scenario: I can access the dimensions modal from the filter badge + When I add a "Period" filter + And I click on the "Period" filter badge + Then the filter modal is opened diff --git a/cypress/integration/ui/dashboard_filter/dashboard_filter.js b/cypress/integration/ui/dashboard_filter/dashboard_filter.js index 3eaadb734..76533e834 100644 --- a/cypress/integration/ui/dashboard_filter/dashboard_filter.js +++ b/cypress/integration/ui/dashboard_filter/dashboard_filter.js @@ -1,15 +1,12 @@ -import { When, Then } from 'cypress-cucumber-preprocessor/steps' +import { Then } from 'cypress-cucumber-preprocessor/steps' import { getDashboardItem, chartSubtitleSel, chartXAxisLabelSel, } from '../../../selectors/dashboardItem' import { - unselectedItemsSel, - filterDimensionsPanelSel, filterBadgeSel, - orgUnitHierarchySel, - orgUnitCheckboxesSel, + dimensionsModalSel, } from '../../../selectors/dashboardFilter' import { dashboards } from '../../../assets/backends' import { EXTENDED_TIMEOUT } from '../../../support/utils' @@ -20,29 +17,6 @@ const FACILITY_TYPE = 'Clinic' const chartItemUid = dashboards.Delivery.items.chart.itemUid -When('I add a {string} filter', dimensionType => { - cy.contains('Add filter').click() - - // open the dimensions modal - cy.get(filterDimensionsPanelSel).contains(dimensionType).click() - - // select an item in the modal - if (dimensionType === 'Period') { - cy.get(unselectedItemsSel).contains(PERIOD).dblclick() - } else if (dimensionType === 'Organisation Unit') { - cy.get(orgUnitHierarchySel, EXTENDED_TIMEOUT).find('.arrow').click() - cy.get(orgUnitHierarchySel, EXTENDED_TIMEOUT) - .find(orgUnitCheckboxesSel, EXTENDED_TIMEOUT) - .contains(OU, EXTENDED_TIMEOUT) - .click() - } else { - cy.get(unselectedItemsSel).contains(FACILITY_TYPE).dblclick() - } - - // confirm to apply the filter - cy.get('button').contains('Confirm').click() -}) - /* Scenario: I add a Period filter */ @@ -87,3 +61,7 @@ Then('the Facility Type filter is applied to the dashboard', () => { .contains(FACILITY_TYPE, EXTENDED_TIMEOUT) .should('be.visible') }) + +Then('the filter modal is opened', () => { + cy.get(dimensionsModalSel, EXTENDED_TIMEOUT).should('be.visible') +}) diff --git a/cypress/integration/ui/responsive_dashboard.feature b/cypress/integration/ui/responsive_dashboard.feature index cac0cddac..23c7adc10 100644 --- a/cypress/integration/ui/responsive_dashboard.feature +++ b/cypress/integration/ui/responsive_dashboard.feature @@ -45,3 +45,11 @@ Feature: Small screen dashboard When I go to small screen And I change url to edit Then the "Delivery" dashboard displays in view mode + + @nonmutating + Scenario: I cannot edit dashboard filter while in small screen + Given I open the "Delivery" dashboard + And I add a "Period" filter + When I go to small screen + And I click on the "Period" filter badge + Then the filter modal is not opened \ No newline at end of file diff --git a/cypress/integration/ui/responsive_dashboard/responsive_dashboard.js b/cypress/integration/ui/responsive_dashboard/responsive_dashboard.js index 1e025a0fb..0bac79e17 100644 --- a/cypress/integration/ui/responsive_dashboard/responsive_dashboard.js +++ b/cypress/integration/ui/responsive_dashboard/responsive_dashboard.js @@ -2,6 +2,7 @@ import { When, Then } from 'cypress-cucumber-preprocessor/steps' import { EXTENDED_TIMEOUT } from '../../../support/utils' import { chartSel } from '../../../selectors/dashboardItem' import { dashboardTitleSel } from '../../../selectors/viewDashboard' +import { dimensionsModalSel } from '../../../selectors/dashboardFilter' const TEST_DASHBOARD_TITLE = 'TEST_DASHBOARD_TITLE' @@ -106,3 +107,7 @@ When('I change url to edit', () => { }) }) }) + +Then('the filter modal is not opened', () => { + cy.get(dimensionsModalSel, EXTENDED_TIMEOUT).should('not.exist') +}) diff --git a/cypress/selectors/dashboardFilter.js b/cypress/selectors/dashboardFilter.js index 24fe3f2e8..338d1b602 100644 --- a/cypress/selectors/dashboardFilter.js +++ b/cypress/selectors/dashboardFilter.js @@ -1,6 +1,10 @@ export const filterBadgeSel = '[data-test="dashboard-filter-badge"]' + export const filterDimensionsPanelSel = '[data-test="dashboard-filter-popover"]' + export const unselectedItemsSel = '[data-test="dhis2-uicore-transfer-sourceoptions"]' -export const orgUnitHierarchySel = '[data-test="ou-dimension-modal"]' + export const orgUnitCheckboxesSel = '*[role="button"]' + +export const dimensionsModalSel = '[data-test="dimension-modal"]' diff --git a/src/components/ItemFilter/FilterDialog.js b/src/components/ItemFilter/FilterDialog.js index b13e7660b..e1ac013e4 100644 --- a/src/components/ItemFilter/FilterDialog.js +++ b/src/components/ItemFilter/FilterDialog.js @@ -113,7 +113,7 @@ const FilterDialog = ({ <> {dimension.id && ( Date: Wed, 24 Feb 2021 13:29:17 +0100 Subject: [PATCH 3/4] fix: use the visible element instead of class --- .../common/{add_filter.js => dashboard_filter.js} | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) rename cypress/integration/common/{add_filter.js => dashboard_filter.js} (91%) diff --git a/cypress/integration/common/add_filter.js b/cypress/integration/common/dashboard_filter.js similarity index 91% rename from cypress/integration/common/add_filter.js rename to cypress/integration/common/dashboard_filter.js index 48684424b..55f6ede6c 100644 --- a/cypress/integration/common/add_filter.js +++ b/cypress/integration/common/dashboard_filter.js @@ -36,9 +36,5 @@ When('I add a {string} filter', dimensionType => { }) When('I click on the {string} filter badge', filterName => { - cy.get(filterBadgeSel) - .find('span') - .not('.badgeSmall') - .contains(filterName) - .click() + cy.get(filterBadgeSel).find('span:visible').contains(filterName).click() }) From 56267ff53a47591d53ad8d3088707d7f7fc06860 Mon Sep 17 00:00:00 2001 From: Jen Jones Arnesen Date: Wed, 24 Feb 2021 13:39:01 +0100 Subject: [PATCH 4/4] fix: missing newline --- cypress/integration/ui/responsive_dashboard.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/integration/ui/responsive_dashboard.feature b/cypress/integration/ui/responsive_dashboard.feature index 23c7adc10..dfbc3d01e 100644 --- a/cypress/integration/ui/responsive_dashboard.feature +++ b/cypress/integration/ui/responsive_dashboard.feature @@ -52,4 +52,4 @@ Feature: Small screen dashboard And I add a "Period" filter When I go to small screen And I click on the "Period" filter badge - Then the filter modal is not opened \ No newline at end of file + Then the filter modal is not opened