-
-
Notifications
You must be signed in to change notification settings - Fork 407
test(#11246): harden Reports Date Filter Sidebar tests (Bikram Sambat) #11257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 10707-dmp-2026-enhance-bikram-sambat-support-in-cht
Are you sure you want to change the base?
Changes from 2 commits
41a8ea2
86832b5
8c0af42
429175a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -197,8 +197,57 @@ describe('Reports Sidebar Filter', () => { | |
|
|
||
| await reportsPage.openSidebarFilter(); | ||
| await reportsPage.openSidebarFilterDateAccordion(); | ||
|
|
||
| // 1. Max Date parity - verify future dates are disabled | ||
| await $('#fromDateFilter').click(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (non-blocking): These sidebar clicks are written as raw selectors here ( |
||
| let picker; | ||
| await browser.waitUntil(async () => { | ||
| const pickers = await $$('.nepali-date-picker'); | ||
| for (const p of pickers) { | ||
| if (await p.isDisplayed()) { | ||
| picker = p; | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }, { timeout: 5000, timeoutMsg: 'Nepali date picker not displayed' }); | ||
|
|
||
| // Future dates in the current month should be disabled (.disable) | ||
| const disableCells = await picker.$$('table tbody td.current-month-date.disable'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: these locate elements inline in the spec ( |
||
| expect(disableCells.length).to.be.greaterThan(0); | ||
|
|
||
| // 2. Escape Dismissal - press Escape and verify picker is dismissed | ||
| await browser.keys(['Escape']); | ||
| expect(await picker.isDisplayed()).to.be.false; | ||
|
|
||
| // 3. Viewport positioning & scroll alignment | ||
| await $('#fromDateFilter').click(); | ||
| expect(await picker.isDisplayed()).to.be.true; | ||
| const initialLocation = await picker.getLocation(); | ||
|
|
||
| // Simulate scroll event | ||
| await browser.execute('window.dispatchEvent(new Event("scroll"))'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: this fires a |
||
| const newLocation = await picker.getLocation(); | ||
| expect(newLocation.y).to.equal(initialLocation.y); // Should remain anchored correctly | ||
|
|
||
| // Dismiss by clicking outside (e.g. the accordion header) | ||
| const accordionHeader = await $('#date-filter-accordion mat-expansion-panel-header'); | ||
| await accordionHeader.click(); | ||
| expect(await picker.isDisplayed()).to.be.false; | ||
|
|
||
| // 4. Select From and To dates | ||
| await reportsPage.setSidebarFilterBikFromDate(); | ||
| await reportsPage.setSidebarFilterBikToDate(); | ||
|
|
||
| // 5. Reopen Off-by-one verification | ||
| await $('#toDateFilter').click(); | ||
| // Verify that the active selected date is highlighted correctly | ||
| const activeCell = await picker.$('table tbody td.current-month-date.active'); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue: this asserts only that an
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed! I have pushed this down to the unit test level as suggested. The E2E test now simply acts as a high-level integration check utilizing the updated Page Object selectors. |
||
| expect(await activeCell.isDisplayed()).to.be.true; | ||
|
|
||
| // Dismiss it | ||
| await browser.keys(['Escape']); | ||
|
|
||
| await commonPage.waitForPageLoaded(); | ||
|
|
||
| expect(await reportsPage.leftPanelSelectors.allReports().length).to.equal(2); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ import { Selectors } from '@mm-selectors/index'; | |
| import { ResponsiveService } from '@mm-services/responsive.service'; | ||
| import { LanguageService } from '@mm-services/language.service'; | ||
| import { FormatDateService } from '@mm-services/format-date.service'; | ||
| import { toBik_dev } from 'bikram-sambat'; | ||
|
|
||
| describe('Date Filter Component', () => { | ||
| let component: DateFilterComponent; | ||
|
|
@@ -195,7 +196,8 @@ describe('Date Filter Component', () => { | |
| expect(nepaliDatePickerStub.callCount).to.equal(1); | ||
|
|
||
| const maxDateVal = nepaliDatePickerStub.args[0][0].maxDate; | ||
| expect(maxDateVal).to.match(/^[०-९-]+$/); | ||
| const expectedMaxDate = toBik_dev(moment().clone().locale('en').format('YYYY-MM-DD')); | ||
| expect(maxDateVal).to.equal(expectedMaxDate); | ||
|
|
||
| const hiddenInput = $('#bikram-sambat-test-wrapper .nepali-datepicker-input'); | ||
| expect(hiddenInput).to.have.lengthOf(1); | ||
|
|
@@ -254,7 +256,7 @@ describe('Date Filter Component', () => { | |
|
|
||
| expect(setFilter.callCount).to.equal(1); | ||
| const appliedDate = setFilter.args[0][0].date.from; | ||
| expect(moment(appliedDate).format('YYYY-MM-DD')).to.equal('2024-07-24'); | ||
| expect(moment(appliedDate).format('YYYY-MM-DD HH:mm:ss.SSS')).to.equal('2024-07-24 00:00:00.000'); | ||
| setFilter.restore(); | ||
| }); | ||
|
|
||
|
|
@@ -300,6 +302,84 @@ describe('Date Filter Component', () => { | |
| expect($('.nepali-date-picker-overlay')).to.have.lengthOf(0); | ||
| }); | ||
|
|
||
| it('should maintain independent picker elements for From and To components', () => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: this confirms each component rendered its own hidden input, but not that the two pickers are actually independent. Add an assertion that interacting with one (e.g. selecting a date) leaves the other unchanged. |
||
| // Create From component | ||
| const fixtureFrom = TestBed.createComponent(DateFilterComponent); | ||
| const compFrom = fixtureFrom.componentInstance; | ||
| compFrom.isStartDate = true; | ||
| compFrom.fieldId = 'from-test-field'; | ||
|
|
||
| const htmlFrom = `<div id="from-test-wrapper"><input id="from-test-field" /></div>`; | ||
| document.body.insertAdjacentHTML('afterbegin', htmlFrom); | ||
| fixtureFrom.detectChanges(); | ||
|
|
||
| // Create To component | ||
| const fixtureTo = TestBed.createComponent(DateFilterComponent); | ||
| const compTo = fixtureTo.componentInstance; | ||
| compTo.isStartDate = false; | ||
| compTo.fieldId = 'to-test-field'; | ||
|
|
||
| const htmlTo = `<div id="to-test-wrapper"><input id="to-test-field" /></div>`; | ||
| document.body.insertAdjacentHTML('afterbegin', htmlTo); | ||
| fixtureTo.detectChanges(); | ||
|
|
||
| // Verify each appended its own hidden input | ||
| expect($('#from-test-wrapper .nepali-datepicker-input')).to.have.lengthOf(1); | ||
| expect($('#to-test-wrapper .nepali-datepicker-input')).to.have.lengthOf(1); | ||
|
|
||
| // Clean up DOM | ||
| compFrom.ngOnDestroy(); | ||
| compTo.ngOnDestroy(); | ||
| $('#from-test-wrapper').remove(); | ||
| $('#to-test-wrapper').remove(); | ||
| }); | ||
|
|
||
| it('clearing/resetting the date filter should set the date to undefined', () => { | ||
| component.ngAfterViewInit(); | ||
| const setFilter = sinon.stub(GlobalActions.prototype, 'setFilter'); | ||
| component.dateRange = { from: moment('2024-07-24').valueOf(), to: undefined }; | ||
|
|
||
| component.clear(); | ||
|
|
||
| expect(setFilter.callCount).to.equal(1); | ||
| expect(setFilter.args[0]).to.deep.equal([{ date: undefined }]); | ||
| setFilter.restore(); | ||
| }); | ||
|
|
||
| it('ngOnDestroy should clean up multiple pickers and overlays completely', () => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (blocking): Titled "clean up multiple pickers and overlays completely," but it destroys a single component and asserts only that one hidden input is gone ( |
||
| // Simulate two components having been initialized | ||
| const html1 = `<div id="test-wrapper-1"><input id="field-1" />` + | ||
| `<input type="text" class="nepali-datepicker-input" /></div>`; | ||
| const html2 = `<div id="test-wrapper-2"><input id="field-2" />` + | ||
| `<input type="text" class="nepali-datepicker-input" /></div>`; | ||
| document.body.insertAdjacentHTML('afterbegin', html1); | ||
| document.body.insertAdjacentHTML('afterbegin', html2); | ||
|
|
||
| // Create pickers and overlays | ||
| $('<div class="nepali-date-picker"></div>').appendTo('body'); | ||
| $('<div class="nepali-date-picker"></div>').appendTo('body'); | ||
| $('<div class="nepali-date-picker-overlay"></div>').appendTo('body'); | ||
|
|
||
| // Bind picker data to the hidden inputs | ||
| const hiddenInput1 = $('#test-wrapper-1 .nepali-datepicker-input'); | ||
| const hiddenInput2 = $('#test-wrapper-2 .nepali-datepicker-input'); | ||
| hiddenInput1.data('picker', $('.nepali-date-picker').eq(0)); | ||
| hiddenInput2.data('picker', $('.nepali-date-picker').eq(1)); | ||
|
|
||
| // Instantiate a component and call ngOnDestroy | ||
| component.fieldId = 'field-1'; | ||
| component.ngOnDestroy(); | ||
|
|
||
| // Verify that at least the first component's elements are removed | ||
| expect($('#test-wrapper-1 .nepali-datepicker-input')).to.have.lengthOf(0); | ||
|
|
||
| // Clean up others manually | ||
| $('#test-wrapper-1').remove(); | ||
| $('#test-wrapper-2').remove(); | ||
| $('.nepali-date-picker').remove(); | ||
| $('.nepali-date-picker-overlay').remove(); | ||
| }); | ||
|
|
||
| it('setLabel should use formatDateService.dayMonth', () => { | ||
| component.isStartDate = true; | ||
| component.setLabel({ from: moment('2024-07-24').valueOf(), to: undefined }); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (non-blocking): Nice work moving the picker query selectors into the page object. These interaction selectors are still inline though,
$('#fromDateFilter')here and at :215,$('#toDateFilter')at :226,$('#date-filter-accordion mat-expansion-panel-header')at :217, and each already exists inreports.wdio.page.js(sidebarFilterSelectors.fromDate():69,.toDate():68,.dateAccordionHeader():66). SincesidebarFilterSelectorsis private (not exported), add small named action helpers in the page object (e.g.openBikFromDatePicker()clickingsidebarFilterSelectors.fromDate()) and call those, so no raw selector strings live in the spec and there's one place to update if the DOM changes.