Skip to content

Commit 1f58cc1

Browse files
committed
add playwright tests for the new feature
1 parent 07c7a55 commit 1f58cc1

File tree

5 files changed

+179
-6
lines changed

5 files changed

+179
-6
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { test as base } from '@playwright/test';
2+
import { DatepickerPwPo } from '../support/datepicker.pw.po';
3+
4+
const test = base.extend<{ datepickerPo: DatepickerPwPo }>({
5+
datepickerPo: async ({ page }, use) => {
6+
const datepickerPo = new DatepickerPwPo(page);
7+
await use(datepickerPo);
8+
},
9+
});
10+
test.describe('Datepicker page testing suite', () => {
11+
let tabSelector: string;
12+
13+
test.beforeEach(async ({ datepickerPo }) => {
14+
tabSelector = datepickerPo.getTabSelector('Overview');
15+
await datepickerPo.navigateTo();
16+
});
17+
18+
test.describe('Unlinked calendar', () => {
19+
let unlinkedCalendars: string;
20+
21+
test.beforeEach(async ({ datepickerPo }) => {
22+
unlinkedCalendars = tabSelector + datepickerPo.exampleDemosArr.unlinkedCalendars;
23+
await datepickerPo.scrollToMenu('Unlinked calendars');
24+
});
25+
26+
test('click should open two calendars', async ({ datepickerPo }) => {
27+
await datepickerPo.clickOnDaterangepickerInput(unlinkedCalendars, 0);
28+
await datepickerPo.waitForElementToBeVisible('bs-daterangepicker-container');
29+
await datepickerPo.expectItemVisible('.bs-datepicker-body', 0);
30+
await datepickerPo.expectItemVisible('.bs-datepicker-body', 1);
31+
});
32+
33+
test('when user goes to previous in the left calendar, right one stays the same', async ({ datepickerPo }) => {
34+
await datepickerPo.clickOnDaterangepickerInput(unlinkedCalendars, 0);
35+
await datepickerPo.waitForElementToBeVisible('bs-daterangepicker-container');
36+
await datepickerPo.expectTextInViewInTheHeader(0, 0, 'October');
37+
await datepickerPo.expectTextInViewInTheHeader(0, 1, '1979');
38+
await datepickerPo.expectTextInViewInTheHeader(1, 0, 'April');
39+
await datepickerPo.expectTextInViewInTheHeader(1, 1, '1985');
40+
await datepickerPo.clickOnNavigation(0, '<');
41+
await datepickerPo.expectTextInViewInTheHeader(0, 0, 'September');
42+
await datepickerPo.expectTextInViewInTheHeader(0, 1, '1979');
43+
await datepickerPo.expectTextInViewInTheHeader(1, 0, 'April');
44+
await datepickerPo.expectTextInViewInTheHeader(1, 1, '1985');
45+
});
46+
47+
test('when user changes mode to month on the calendar, right one stays the same', async ({ datepickerPo }) => {
48+
await datepickerPo.clickOnDaterangepickerInput(unlinkedCalendars, 0);
49+
await datepickerPo.waitForElementToBeVisible('bs-daterangepicker-container');
50+
await datepickerPo.expectTextInViewInTheHeader(0, 0, 'October');
51+
await datepickerPo.expectTextInViewInTheHeader(0, 1, '1979');
52+
await datepickerPo.expectTextInViewInTheHeader(1, 0, 'April');
53+
await datepickerPo.expectTextInViewInTheHeader(1, 1, '1985');
54+
await datepickerPo.clickOnNavigation(0, 'month');
55+
await datepickerPo.expectTextInViewInTheHeader(0, 0, '1979');
56+
await datepickerPo.expectTextInViewInTheBody(0, 'October', true);
57+
await datepickerPo.expectTextInViewInTheBody(0, 'September', true);
58+
await datepickerPo.expectTextInViewInTheHeader(1, 0, 'April');
59+
await datepickerPo.expectTextInViewInTheHeader(1, 1, '1985');
60+
await datepickerPo.expectTextInViewInTheBody(1, 'October', false);
61+
await datepickerPo.expectTextInViewInTheBody(1, 'September', false);
62+
});
63+
});
64+
65+
});
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Todo: remove eslint-disable
2+
/* eslint-disable @typescript-eslint/ban-ts-comment,@typescript-eslint/no-explicit-any */
3+
import { BasePo } from './base.po';
4+
import { expect } from '@playwright/test';
5+
6+
export class DatepickerPwPo extends BasePo {
7+
override pageUrl = '/ngx-bootstrap/components/datepicker';
8+
pageTitle = 'Datepicker';
9+
ghLinkToComponent = 'https://github.com/valor-software/ngx-bootstrap/tree/development/src/datepicker';
10+
11+
datepickerInput = 'input[bsdatepicker]';
12+
daterangepickerInput = 'input[bsdaterangepicker]';
13+
datepickerNavView = 'bs-datepicker-navigation-view';
14+
datepickerContainer = 'bs-datepicker-container';
15+
datepickerInlineContainer = 'bs-datepicker-inline-container';
16+
daterangepickerContainer = 'bs-daterangepicker-container';
17+
datepickerBodyDaysView = 'bs-days-calendar-view';
18+
datepickerBodyMonthView = 'bs-month-calendar-view';
19+
datepickerBodyYearsView = 'bs-years-calendar-view';
20+
daterangepickerQuickSelectContainer = 'bs-custom-date-view';
21+
monthNames = [
22+
'January',
23+
'February',
24+
'March',
25+
'April',
26+
'May',
27+
'June',
28+
'July',
29+
'August',
30+
'September',
31+
'October',
32+
'November',
33+
'December',
34+
'January'
35+
];
36+
locales = [];
37+
38+
exampleDemosArr = {
39+
unlinkedCalendars: ' datepicker-unlinked-calendar-views'
40+
};
41+
42+
async clickOnDatepickerInput(baseSelector: string, datepickerIndex = 0) {
43+
const datepicker = this.page.locator(`${baseSelector} ${this.datepickerInput}`).nth(datepickerIndex);
44+
await datepicker.waitFor({state: 'visible', timeout: 10000});
45+
await datepicker.click();
46+
}
47+
48+
async clickOnDaterangepickerInput(baseSelector: string, dateRangeIndex = 0) {
49+
const datepicker = this.page.locator(`${baseSelector} ${this.daterangepickerInput}`).nth(dateRangeIndex);
50+
await datepicker.waitFor({state: 'visible', timeout: 10000});
51+
await datepicker.click();
52+
}
53+
async waitForElementToBeVisible(selector: string) {
54+
await this.page.waitForSelector(selector, { state: 'visible', timeout: 10000 });
55+
}
56+
async expectItemVisible(selector: string, index: number) {
57+
await expect(await this.page.locator(selector).nth(index)).toBeVisible({visible: true, timeout: 10000});
58+
}
59+
60+
async expectTextInViewInTheHeader(calendarIndex: number, currentIndex: number, text: string) {
61+
// this is needed so it won't return up with the inline range pickers that are also on the page
62+
const mainPopup = await this.page.locator('bs-daterangepicker-container');
63+
const header = await mainPopup.locator('.bs-datepicker-head').nth(calendarIndex);
64+
await expect(header).toBeVisible({visible: true, timeout: 10000});
65+
const current = await header.locator('.current').nth(currentIndex);
66+
await expect(current).toBeVisible({visible: true, timeout: 10000});
67+
const button = await current.locator('span');
68+
await expect(button).toBeVisible({visible: true, timeout: 10000});
69+
await expect(button).toHaveText(text);
70+
}
71+
72+
async clickOnNavigation(dateRangeIndex = 0, navigationItem: '<' | '>' | 'month' | 'year' ) {
73+
const mainPopup = await this.page.locator('bs-daterangepicker-container');
74+
const datepicker = await mainPopup.locator(`.bs-datepicker-head`).nth(dateRangeIndex);
75+
switch (navigationItem) {
76+
case '<':
77+
await datepicker.locator('.previous').click();
78+
break;
79+
80+
case '>':
81+
await datepicker.locator('.next').click();
82+
break;
83+
84+
case 'month':
85+
await datepicker.locator('.current').nth(0).click();
86+
break;
87+
88+
case 'year':
89+
await datepicker.locator('.current').nth(1).click();
90+
break;
91+
92+
default:
93+
throw new Error('Unknown navigation item, correct: <, >, month, year');
94+
}
95+
await this.page.waitForTimeout(200); // waiting for the navigation to happen
96+
}
97+
async expectTextInViewInTheBody(calendarIndex: number, text: string, visible: boolean) {
98+
// this is needed so it won't return up with the inline range pickers that are also on the page
99+
const mainPopup = await this.page.locator('bs-daterangepicker-container');
100+
const body = await mainPopup.locator('.bs-datepicker-body').nth(calendarIndex);
101+
if (visible) {
102+
await expect(body.getByText(text).first()).toBeVisible();
103+
} else {
104+
await expect(body.getByText(text)).toHaveCount(0);
105+
}
106+
}
107+
108+
}

libs/doc-pages/datepicker/src/lib/datepicker-section.list.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ export const demoComponentContent: ContentSection[] = [
481481
outlet: KeepDatesOutOfRulesComponent
482482
},
483483
{
484-
title: "Allow separately moving calendars in DateRangePicker",
484+
title: "Unlinked calendars",
485485
anchor: 'unlinked-calendar-views',
486486
component: require('!!raw-loader!./demos/unlinked-calendar-views/unlinked-calendar-views.component'),
487487
html: require('!!raw-loader!./demos/unlinked-calendar-views/unlinked-calendar-views.component.html'),
@@ -747,7 +747,7 @@ export const demoComponentContent: ContentSection[] = [
747747
outlet: KeepDatesOutOfRulesComponent
748748
},
749749
{
750-
title: "Allow separately moving calendars in DateRangePicker",
750+
title: "Unlinked calendars",
751751
anchor: 'unlinked-calendar-views',
752752
outlet: UnlinkedCalendarsComponent
753753
},

libs/doc-pages/datepicker/src/lib/demos/unlinked-calendar-views/unlinked-calendar-views.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { Component } from '@angular/core';
22

33
@Component({
44
// eslint-disable-next-line @angular-eslint/component-selector
5-
selector: 'unlinked-calendar-views',
5+
selector: 'datepicker-unlinked-calendar-views',
66
templateUrl: './unlinked-calendar-views.component.html',
77
standalone: false
88
})
99
export class UnlinkedCalendarsComponent {
1010
dateRangePickerValue?: (Date | undefined)[];
11-
range1: Date = new Date(2020, 5, 10);
12-
range2: Date = new Date(2022, 8, 10);
11+
range1: Date = new Date(1979, 9, 27);
12+
range2: Date = new Date(1985, 3, 2);
1313
ngOnInit(): void {
1414
this.dateRangePickerValue = [this.range1, this.range2];
1515
}

src/datepicker/reducer/bs-datepicker.reducer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ function calculateReducer(state: BsDatepickerState): BsDatepickerState {
239239
const checkedMode = state.viewStates?.length > calendarIndex ? state.viewStates[calendarIndex]?.mode ?? state.view.mode : state.view.mode;
240240
if (checkedMode === 'day' && state.monthViewOptions != null) {
241241
if (calendarIndex == 0) {
242-
if (!state.unlinkedCalendars && state.showPreviousMonth && state.selectedRange && state.selectedRange.length === 0) {
242+
if (state.showPreviousMonth && state.selectedRange && state.selectedRange.length === 0) {
243243
viewDate = shiftDate(viewDate, { month: -1 });
244244
}
245245
state.monthViewOptions.firstDayOfWeek = getLocale(state.locale).firstDayOfWeek();

0 commit comments

Comments
 (0)