diff --git a/semcore/date-picker/CHANGELOG.md b/semcore/date-picker/CHANGELOG.md index 1d34d5d3d1..84326d8a95 100644 --- a/semcore/date-picker/CHANGELOG.md +++ b/semcore/date-picker/CHANGELOG.md @@ -2,6 +2,12 @@ CHANGELOG.md standards are inspired by [keepachangelog.com](https://keepachangelog.com/en/1.0.0/). +## [16.2.2] - 2025-11-10 + +### Fixed + +- Space key interactions in Date Picker (unable to switch months, apply Today, keep selected date, etc.) + ## [16.2.1] - 2025-10-29 ### Changed diff --git a/semcore/date-picker/__tests__/__image_snapshots__/daterangecomparator-verify-renders-correctly-monthes.png b/semcore/date-picker/__tests__/__image_snapshots__/daterangecomparator-verify-renders-correctly-monthes.png deleted file mode 100644 index b8c2834dd7..0000000000 Binary files a/semcore/date-picker/__tests__/__image_snapshots__/daterangecomparator-verify-renders-correctly-monthes.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/__image_snapshots__/daterangecomparator-verify-renders-correctly.png b/semcore/date-picker/__tests__/__image_snapshots__/daterangecomparator-verify-renders-correctly.png deleted file mode 100644 index a6f31bc136..0000000000 Binary files a/semcore/date-picker/__tests__/__image_snapshots__/daterangecomparator-verify-renders-correctly.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-localized-placeholder-renders-correctly.png b/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-localized-placeholder-renders-correctly.png deleted file mode 100644 index f926f7e735..0000000000 Binary files a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-localized-placeholder-renders-correctly.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-picker-renders-correctly-if-one-day-is-selected.png b/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-picker-renders-correctly-if-one-day-is-selected.png deleted file mode 100644 index e7a46bdc26..0000000000 Binary files a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-picker-renders-correctly-if-one-day-is-selected.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-picker-renders-correctly-if-the-same-month-of-a-different-year-is-selected.png b/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-picker-renders-correctly-if-the-same-month-of-a-different-year-is-selected.png deleted file mode 100644 index 5f89981a2e..0000000000 Binary files a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-picker-renders-correctly-if-the-same-month-of-a-different-year-is-selected.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-renders-correctly-with-empty-period.png b/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-renders-correctly-with-empty-period.png deleted file mode 100644 index 23f944e2a3..0000000000 Binary files a/semcore/date-picker/__tests__/__image_snapshots__/daterangepicker-verify-renders-correctly-with-empty-period.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.axe-test.tsx b/semcore/date-picker/__tests__/date-picker.axe-test.tsx index 72fb2f4e37..0c76158d81 100644 --- a/semcore/date-picker/__tests__/date-picker.axe-test.tsx +++ b/semcore/date-picker/__tests__/date-picker.axe-test.tsx @@ -1,12 +1,10 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, getAccessibilityViolations, test } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; -test.describe('DatePicker', () => { +test.describe(`@date-picker ${TAG.ACCESSIBILITY}`, () => { test('Single date', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); // base check { @@ -27,10 +25,7 @@ test.describe('DatePicker', () => { }); test('Custom date range', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx', 'en'); // base check { @@ -51,10 +46,7 @@ test.describe('DatePicker', () => { }); test('Custom day', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_day.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_day.tsx', 'en'); // base check { @@ -75,10 +67,7 @@ test.describe('DatePicker', () => { }); test('Custom header', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_header.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_header.tsx', 'en'); // base check { @@ -99,10 +88,7 @@ test.describe('DatePicker', () => { }); test('Date range comparator', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); // base check { @@ -123,11 +109,7 @@ test.describe('DatePicker', () => { }); test('Date range comparator advanced', async ({ page }) => { - const standPath = - 'stories/components/date-picker/docs/examples/date_range_comparator_advanced_use.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator_advanced_use.tsx', 'en'); // base check { @@ -148,10 +130,7 @@ test.describe('DatePicker', () => { }); test('Disabled dates', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/disabled_dates.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/disabled_dates.tsx', 'en'); // base check { @@ -172,11 +151,7 @@ test.describe('DatePicker', () => { }); test('Month range comparator', async ({ page }) => { - const standPath = - 'stories/components/date-picker/docs/examples/month_range_comparator_advanced_use.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/month_range_comparator_advanced_use.tsx', 'en'); // base check { @@ -197,10 +172,7 @@ test.describe('DatePicker', () => { }); test('Month range picker', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); // base check { @@ -221,10 +193,7 @@ test.describe('DatePicker', () => { }); test('Trigger and popper', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx', 'en'); // base check { @@ -245,10 +214,7 @@ test.describe('DatePicker', () => { }); test('Week picker', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/week_picker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); + await loadPage(page, 'stories/components/date-picker/docs/examples/week_picker.tsx', 'en'); // base check { diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx b/semcore/date-picker/__tests__/date-picker.browser-test.tsx index 3d00839256..f35364f839 100644 --- a/semcore/date-picker/__tests__/date-picker.browser-test.tsx +++ b/semcore/date-picker/__tests__/date-picker.browser-test.tsx @@ -1,1205 +1,1130 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, test } from '@semcore/testing-utils/playwright'; +import type { Page } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; + +import { checkStyle } from './utils'; + +export const locators = { + + button: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('button', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + datePickerTrigger: (page: Page, index?: number) => { + const base = page.locator('[data-ui-name="DatePicker.Trigger"]'); + return typeof index === 'number' ? base.nth(index) : base; + }, + calendar: (page: Page) => page.locator('[data-ui-name="DatePicker.Calendar"]'), + weekDaysRow: (page: Page) => page.locator('[data-ui-name="CalendarWeekDays"]'), + divider: (page: Page) => page.locator('[data-ui-name="Divider"]'), + cells: (page: Page, index?: number) => { + const base = page.getByRole('gridcell'); + return typeof index === 'number' ? base.nth(index) : base; + }, + popper: (page: Page) => page.getByRole('dialog'), + title: (page: Page) => page.locator('[data-ui-name="DatePicker.Title"]'), + +}; + +/* ===================================================== +@visual +Visual states, hover and focus styles, paddings, margins, and snapshots. +===================================================== */ +test.describe(`${TAG.VISUAL}`, () => { + test.describe('Date Picker Trigger', () => { + test('Verify trigger states when entering date manually', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); + + const screenshotsClip = (await locators.datePickerTrigger(page, 0).boundingBox())!; + screenshotsClip.x -= 4; + screenshotsClip.y -= 4; + screenshotsClip.width += 8; + screenshotsClip.height += 8; -test.describe('Date Picker Trigger', () => { - test('Verify trigger states when entering date manually', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePicker = await page.locator('[data-ui-name="DatePicker.Trigger"]'); - const screenshotsClip = (await datePicker.first().boundingBox())!; - screenshotsClip.x -= 4; - screenshotsClip.y -= 4; - screenshotsClip.width += 8; - screenshotsClip.height += 8; - - await page.keyboard.press('Tab'); - await page.keyboard.type('052'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.type('92000'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - }); + await page.keyboard.press('Tab'); + await page.keyboard.type('052'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.type('92000'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - test('Verify trigger states and props', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/day-trigger.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('ArrowRight'); + for (let i = 0; i < 5; i++) await page.keyboard.press('Backspace'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + }); - await page.setContent(htmlContent); + test('Verify trigger states and props', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/day-trigger.tsx', 'en'); - await expect(page).toHaveScreenshot(); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); + await expect(page).toHaveScreenshot(); + for (let i = 0; i < 4; i++) await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); + }); }); -}); -test.describe('DayPicker with today button', () => { - test('Verify roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); + test.describe('DayPicker with today button', () => { + test('Verify datepicker with Today button styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); - const datePickerTrigger = page.locator('[data-ui-name="DatePicker.Trigger"]'); - const inputTrigger = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); + const selectedCell = page.locator('[data-ui-name="CalendarDays.Unit"][class*="Selected"]'); - await test.step('Verify trigger aria label', async () => { - await expect(datePickerTrigger.first()).toHaveAttribute('aria-label', 'Date field'); - }); + await test.step('Verify trigger margins', async () => { + await checkStyle(locators.datePickerTrigger(page, 0), { marginTop: '8px' }); + }); - await test.step('Verify trigger SVG attributes', async () => { - const svg = datePickerTrigger.locator('svg'); - const svgAttributes = [ - ['tabindex', '-1'], - ['aria-hidden', 'true'], - ['width', '16'], - ['height', '16'], - ]; - - for (const [attr, value] of svgAttributes) { - await expect(svg).toHaveAttribute(attr, value); - } - }); + await test.step('Verify header button hover', async () => { + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Verify input trigger attributes', async () => { - const inputAttributes = [ - ['aria-invalid', 'false'], - ['role', 'combobox'], - ['aria-label', 'Date'], - ['inputmode', 'numeric'], - ]; - - for (const [attr, value] of inputAttributes) { - await expect(inputTrigger).toHaveAttribute(attr, value); - } - }); + await locators.button(page, 'Previous month').hover(); + await expect(page).toHaveScreenshot(); + }); - await datePickerTrigger.first().click(); + await test.step('Verify disabled date styles', async () => { + await checkStyle(locators.cells(page, 0), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - await test.step('Verify popper attributes', async () => { - const popperAttributes = [ - ['tabindex', '0'], - ['role', 'dialog'], - ['data-popper-placement', 'bottom-start'], - ]; + await test.step('Verify style of available date', async () => { + await checkStyle(locators.cells(page, 2), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - for (const [attr, value] of popperAttributes) { - await expect(popper).toHaveAttribute(attr, value); - } - }); + await test.step('Verify hover style of available date', async () => { + await locators.cells(page, 8).hover(); + await expect(page).toHaveScreenshot(); + }); - await test.step('Verify popper header attributes', async () => { - const headerLocators = [ - { - locator: '[data-ui-name="DatePicker.Prev"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Previous month'], - ], - }, - { locator: '[data-ui-name="DatePicker.Title"]', attrs: [['aria-live', 'polite']] }, - { - locator: '[data-ui-name="DatePicker.Next"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Next month'], - ], - }, - ]; - - for (const { locator, attrs } of headerLocators) { - const element = page.locator(locator); - for (const [attr, value] of attrs) { - await expect(element).toHaveAttribute(attr, value); - } - } - }); + await test.step('Verify style of selected date', async () => { + await checkStyle(selectedCell, { + color: 'rgb(255, 255, 255)', + backgroundColor: 'rgb(43, 179, 255)', + margin: '4px 0px 0px', + width: '32px', + height: '32px', + }); + }); - await test.step('Verify calendar attributes', async () => { - const calendar = page.locator('[data-ui-name="DatePicker.Calendar"]'); - await expect(calendar).toHaveAttribute('tabindex', '0'); - await expect(calendar).toHaveAttribute('role', 'grid'); - await expect(calendar).toHaveAttribute('disabled', ''); - }); + await test.step('Verify hover style of selected date', async () => { + await selectedCell.hover(); + await expect(page).toHaveScreenshot(); + }); - await test.step('Verify weekdays attributes', async () => { - const weekDaysRow = page.locator('[data-ui-name="CalendarWeekDays"]'); - await expect(weekDaysRow).toHaveAttribute('role', 'row'); - - const weekDays = weekDaysRow.locator('[data-ui-name="CalendarWeekDays.Unit"]'); - const daysOfWeek = [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ]; - - for (const [i, dayName] of daysOfWeek.entries()) { - const day = weekDays.nth(i); - await expect(day).toHaveAttribute('role', 'columnheader'); - await expect(day).toHaveAttribute('aria-label', dayName); - - const dayText = (await day.textContent())?.trim(); - expect(dayText).toBe(dayName.slice(0, 3)); - } + await test.step('Verify hover style for today button', async () => { + await locators.button(page, 'Today').hover(); + await expect(page).toHaveScreenshot(); + }); }); + }); - await test.step('Verify days attributes', async () => { - const cells = page.locator('[role="gridcell"]'); - const cellCount = await cells.count(); - - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; - - const dayAttributes = [ - ['role', 'gridcell'], - ['aria-colindex'], - ['aria-rowindex'], - ['aria-selected', 'false'], - ['aria-hidden', 'false'], - ]; + test.describe('DayPicker with custom days', () => { + test('Verify datepicker with custom days styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/custom_day_test.tsx', 'en'); - for (const [attr, value] of dayAttributes) { - if (value !== undefined) { - await expect(cell).toHaveAttribute(attr, value); - } else { - await expect(cell).toHaveAttribute(attr); - } + const selectedCell = page.locator( + '[data-ui-name="CalendarDays.Unit"][class*="__startSelected_"][class*="__endSelected_"]', + ); + + // Helper function to check style properties + const checkStyle = async (element: any, expectedStyles: any) => { + for (const [property, expectedValue] of Object.entries(expectedStyles)) { + const actualValue = await element.evaluate( + (el: any, property: any) => getComputedStyle(el)[property], + property, + ); + expect(actualValue).toBe(expectedValue); } + }; - const date = new Date(ariaLabel); - const isCurrentMonth = date.getMonth() === 5; // June + await test.step('Verify trigger margins', async () => { + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - const hasDisabled = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + await checkStyle(locators.datePickerTrigger(page, 0), { marginTop: '8px' }); + }); - if (isCurrentMonth) { - expect(hasDisabled).toBe(false); - } else { - expect(hasDisabled).toBe(true); - } - expect(ariaDisabled).toBe('false'); + await test.step('Verify hover disabled date', async () => { + await checkStyle(locators.cells(page, 0), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - const text = (await cell.textContent())?.trim(); - expect(text).not.toBe(''); - } - }); + await test.step('Verify style of available date', async () => { + await checkStyle(locators.cells(page, 10), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - await test.step('Verify divider attributes', async () => { - const divider = page.locator('[data-ui-name="Divider"]'); - const dividerAttributes = [ - ['orientation', 'horizontal'], - ['aria-orientation', 'horizontal'], - ['role', 'separator'], - ]; - - for (const [attr, value] of dividerAttributes) { - await expect(divider).toHaveAttribute(attr, value); - } - }); + await test.step('Verify hover style of available date', async () => { + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await test.step('Verify today button attributes', async () => { - const todayButton = page.locator('[data-ui-name="Button"]'); - const todayAttributes = [['type', 'button']]; + page.locator('input[data-ui-name="DatePicker.Trigger"]').fill('05.05.2024'); + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + }); - for (const [attr, value] of todayAttributes) { - await expect(todayButton).toHaveAttribute(attr, value); - } + await test.step('Verify style of selected date', async () => { + await checkStyle(selectedCell, { + color: 'rgb(255, 255, 255)', + backgroundColor: 'rgb(43, 179, 255)', + margin: '4px 0px 0px', + width: '32px', + }); + }); }); }); - test('Verify datepicker with Today button styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePickerTrigger = page.locator('[data-ui-name="DatePicker.Trigger"]'); - const prevButton = page.locator('[data-ui-name="DatePicker.Prev"]'); - const cells = page.locator('[role="gridcell"]'); - const todayButton = page.locator('[data-ui-name="Button"]'); - const selectedCell = page.locator('[data-ui-name="CalendarDays.Unit"][class*="Selected"]'); - - // Helper function to check style properties - const checkStyle = async (element: any, expectedStyles: any) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; + test.describe('DayPikcer trigger and popper', () => { + test('Verify mouse interactions when component uses expanded trigger and popper', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx', 'en'); - await test.step('Verify trigger margins', async () => { - await checkStyle(datePickerTrigger.first(), { marginTop: '8px' }); - }); + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - await test.step('Verify header button hover', async () => { - await datePickerTrigger.first().click(); - await prevButton.hover(); - await expect(page).toHaveScreenshot(); - }); + await test.step('Fill input manually and open calendar', async () => { + await input.fill('04042022'); + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Verify disabled date styles', async () => { - await checkStyle(cells.first(), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', + await expect(page).toHaveScreenshot(); }); }); + }); - await test.step('Verify style of available date', async () => { - await checkStyle(cells.nth(2), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }); - }); + test.describe('Calendar props and date picker', () => { + test('Verify all calendar props work good', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@propgress-bar'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/calendar_props.tsx', 'en'); - await test.step('Verify hover style of available date', async () => { - await cells.nth(8).hover(); - await expect(page).toHaveScreenshot(); - }); + await page.keyboard.press('Tab'); + await page.keyboard.type('03032025'); - await test.step('Verify style of selected date', async () => { - await checkStyle(selectedCell, { - color: 'rgb(255, 255, 255)', - backgroundColor: 'rgb(43, 179, 255)', - margin: '4px 0px 0px', - width: '32px', - height: '32px', - }); - }); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Verify hover style of selected date', async () => { - await selectedCell.hover(); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); await expect(page).toHaveScreenshot(); }); - await test.step('Verify hover style for today button', async () => { - await todayButton.hover(); + test('Verify all date picker props work good', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/date-picker-props.tsx', 'en'); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + + await page.keyboard.press('Tab'); + await locators.button(page, 'Previous month').hover(); await expect(page).toHaveScreenshot(); }); }); +}); - test('Verify datepicker with today button by mouse interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); +/* ===================================================== +@functional +Keyboard and mouse interactions - no snapshots here. +We verify states, visibility, and attributes. +===================================================== */ +test.describe(`${TAG.FUNCTIONAL}`, () => { + test.describe('DayPicker with today button', () => { + test('Verify roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); + + const inputTrigger = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + + await test.step('Verify trigger aria label', async () => { + await expect(locators.datePickerTrigger(page, 0)).toHaveAttribute('aria-label', 'Date field'); + }); - await page.setContent(htmlContent); + await test.step('Verify trigger SVG attributes', async () => { + const svg = locators.datePickerTrigger(page).locator('svg'); + const svgAttributes = [ + ['tabindex', '-1'], + ['aria-hidden', 'true'], + ['width', '16'], + ['height', '16'], + ]; - const datePickerTrigger = page.locator('[data-ui-name="DatePicker.Trigger"]').first(); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DatePicker.Next"]'); - const todayButton = page.locator('[data-ui-name="Button"]'); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const cells = page.locator('[role="gridcell"]'); + for (const [attr, value] of svgAttributes) { + await expect(svg).toHaveAttribute(attr, value); + } + }); - const initialValue = await input.inputValue(); + await test.step('Verify input trigger attributes', async () => { + const inputAttributes = [ + ['aria-invalid', 'false'], + ['role', 'combobox'], + ['aria-label', 'Date'], + ['inputmode', 'numeric'], + ]; - await test.step('Open and close datepicker popper', async () => { - await datePickerTrigger.click(); - await expect(popper).toBeVisible(); + for (const [attr, value] of inputAttributes) { + await expect(inputTrigger).toHaveAttribute(attr, value); + } + }); - await datePickerTrigger.click(); - await expect(popper).not.toBeVisible(); + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await datePickerTrigger.click(); - await expect(popper).toBeVisible(); - }); + await test.step('Verify popper attributes', async () => { + const popperAttributes = [ + ['tabindex', '0'], + ['data-popper-placement', 'bottom-start'], + ]; - await test.step('Navigate months and verify title changes', async () => { - const initialTitle = await headTitle.textContent(); + for (const [attr, value] of popperAttributes) { + await expect(locators.popper(page)).toHaveAttribute(attr, value); + } + }); - await headPrev.click(); - await expect(headTitle).not.toHaveText(initialTitle!); + await test.step('Verify popper header attributes', async () => { + const headerLocators = [ + { locator: '[data-ui-name="DatePicker.Title"]', attrs: [['aria-live', 'polite']] }, + ]; - await headNext.click(); - await expect(headTitle).toHaveText(initialTitle!); - }); + for (const { locator, attrs } of headerLocators) { + const element = page.locator(locator); + for (const [attr, value] of attrs) { + await expect(element).toHaveAttribute(attr, value); + } + } + }); - await test.step('Select date and today and input value changes', async () => { - await cells.nth(15).click(); - await expect(popper).not.toBeVisible(); + await test.step('Verify calendar attributes', async () => { + await expect(locators.calendar(page)).toHaveAttribute('tabindex', '0'); + await expect(locators.calendar(page)).toHaveAttribute('role', 'grid'); + await expect(locators.calendar(page)).toHaveAttribute('disabled', ''); + }); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); + await test.step('Verify weekdays attributes', async () => { + await expect(locators.weekDaysRow(page)).toHaveAttribute('role', 'row'); + + const weekDays = locators.weekDaysRow(page).locator('[data-ui-name="CalendarWeekDays.Unit"]'); + const daysOfWeek = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; - await datePickerTrigger.click(); - await todayButton.click(); - await expect(popper).not.toBeVisible(); + for (const [i, dayName] of daysOfWeek.entries()) { + const day = weekDays.nth(i); + await expect(day).toHaveAttribute('role', 'columnheader'); + await expect(day).toHaveAttribute('aria-label', dayName); - const finalValue = await input.inputValue(); - expect(finalValue).not.toBe(newValue); - }); - }); + const dayText = (await day.textContent())?.trim(); + expect(dayText).toBe(dayName.slice(0, 3)); + } + }); - test('Verify datepicker with today button by keyboard interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const trigger = page.locator('[data-ui-name="DatePicker.Trigger"]').first(); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const prev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const title = page.locator('[data-ui-name="DatePicker.Title"]'); - const next = page.locator('[data-ui-name="DatePicker.Next"]'); - const todayButton = page.locator('[data-ui-name="Button"]'); - const calendar = page.locator('[data-ui-name="DatePicker.Calendar"]'); - const highlightedCell = page.locator( - '[data-ui-name="CalendarDays.Unit"][class*="highlighted"]', - ); - - const initialValue = await input.inputValue(); - - await test.step('Open datepicker with Enter', async () => { - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(200); - await expect(popper).toBeVisible(); - await expect(trigger).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); + await test.step('Verify days attributes', async () => { + const cells = page.locator('[role="gridcell"]'); + const cellCount = await cells.count(); + + for (let i = 0; i < cellCount; i++) { + const cell = cells.nth(i); + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; + + const dayAttributes = [ + ['role', 'gridcell'], + ['aria-colindex'], + ['aria-rowindex'], + ['aria-selected', 'false'], + ['aria-hidden', 'false'], + ]; + + for (const [attr, value] of dayAttributes) { + if (value !== undefined) { + await expect(cell).toHaveAttribute(attr, value); + } else { + await expect(cell).toHaveAttribute(attr); + } + } - await test.step('Close datepicker with Escape', async () => { - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); - await expect(input).toBeFocused(); - }); + const date = new Date(ariaLabel); + const isCurrentMonth = date.getMonth() === 5; // June - await test.step('Reopen datepicker with Space', async () => { - await page.keyboard.press('Space'); - await page.waitForTimeout(200); - await expect(popper).toBeVisible(); - await expect(trigger).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); + const hasDisabled = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - await test.step('Navigate to prev button and change month', async () => { - await page.keyboard.press('Tab'); - await expect(prev).toBeFocused(); - await prev.hover(); - const initialTitle = await title.textContent(); + if (isCurrentMonth) { + expect(hasDisabled).toBe(false); + } else { + expect(hasDisabled).toBe(true); + } + expect(ariaDisabled).toBe('false'); - await page.keyboard.press('Enter'); - const titleAfterFirstEnter = await title.textContent(); - expect(titleAfterFirstEnter).not.toBe(initialTitle); - await expect(title).not.toHaveText(initialTitle!); + const text = (await cell.textContent())?.trim(); + expect(text).not.toBe(''); + } + }); - await page.keyboard.press('Tab'); - await expect(next).toBeFocused(); + await test.step('Verify divider attributes', async () => { + const dividerAttributes = [ + ['orientation', 'horizontal'], + ['aria-orientation', 'horizontal'], + ['role', 'separator'], + ]; - await page.keyboard.press('Enter'); - const titleAfterSecondEnter = await title.textContent(); - expect(titleAfterSecondEnter).toBe(initialTitle); + for (const [attr, value] of dividerAttributes) { + await expect(locators.divider(page)).toHaveAttribute(attr, value); + } + }); }); - await test.step('Navigate to calendar and today button', async () => { - await page.keyboard.press('Shift+Tab'); - await expect(prev).toBeFocused(); + test('Verify datepicker with today button by mouse interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(calendar).toBeFocused(); + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - await page.keyboard.press('Tab'); - await expect(todayButton).toBeFocused(); + const initialValue = await input.inputValue(); - await page.keyboard.press('Shift+Tab'); - await expect(calendar).toBeFocused(); - }); + await test.step('Open and close datepicker popper', async () => { + await locators.datePickerTrigger(page).first().click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Navigate in calendar and select date', async () => { - await page.keyboard.press('ArrowUp'); - await expect(highlightedCell).toBeVisible(); - - const activeElementHandle = await page.evaluateHandle(() => document.activeElement); - const isFocusedElementHighlighted = await highlightedCell.evaluate( - (el, active) => el === active, - activeElementHandle, - ); - expect(isFocusedElementHighlighted).toBe(true); + await locators.datePickerTrigger(page).first().click(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await page.keyboard.press('Enter'); - await expect(popper).not.toBeVisible(); + await locators.datePickerTrigger(page).first().click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + }); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); + await test.step('Navigate months and verify title changes', async () => { + const initialTitle = await locators.title(page).textContent(); - await page.keyboard.press('Enter'); - await page.waitForTimeout(200); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').click(); + await expect(locators.title(page)).not.toHaveText(initialTitle!); - await expect(popper).not.toBeVisible(); - const newValue2 = await input.inputValue(); - expect(newValue2).not.toBe(newValue); - }); + await locators.button(page, 'Next month').click(); + await expect(locators.title(page)).toHaveText(initialTitle!); + }); - await test.step('Select today by Today button', async () => { - await page.keyboard.press('Enter'); - await page.waitForTimeout(200); - await page.keyboard.press('Shift+Tab'); - await expect(todayButton).toBeFocused(); - const newValue2 = await input.inputValue(); + await test.step('Select date and today and input value changes', async () => { + await locators.cells(page).nth(15).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await page.keyboard.press('Enter'); - await expect(popper).not.toBeVisible(); + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); - const newValue3 = await input.inputValue(); - expect(newValue3).not.toBe(newValue2); - }); - }); -}); + await locators.datePickerTrigger(page).first().click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); -test.describe('DayPicker with custom days', () => { - test('Verify custom days roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/custom_day_test.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await locators.button(page, 'Today').click(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await page.setContent(htmlContent); + const finalValue = await input.inputValue(); + expect(finalValue).not.toBe(newValue); + }); + }); - const datePickerTrigger = page.locator('[data-ui-name="DatePicker.Trigger"]'); + test('Verify datepicker with today button by keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); - await test.step('Verify trigger SVG attributes', async () => { - const svg = datePickerTrigger.locator('svg'); - const svgAttributes = [ - ['tabindex', '-1'], - ['aria-hidden', 'true'], - ['width', '16'], - ['height', '16'], - ]; + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + const highlightedCell = page.locator( + '[data-ui-name="CalendarDays.Unit"][class*="highlighted"]', + ); - for (const [attr, value] of svgAttributes) { - await expect(svg).toHaveAttribute(attr, value); - } - }); + const initialValue = await input.inputValue(); - const triggerAttributes = [{ name: 'aria-label', value: 'Date field' }]; + await test.step('Open datepicker with Enter', async () => { + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await expect(locators.popper(page)).toBeVisible(); + await expect(locators.datePickerTrigger(page, 2)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); - await test.step('Verify trigger attributes', async () => { - for (const { name, value } of triggerAttributes) { - await expect(datePickerTrigger.nth(0)).toHaveAttribute(name, value); - } - }); + await test.step('Close datepicker with Escape', async () => { + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + await expect(input).toBeFocused(); + }); - const inputTrigger = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - await test.step('Verify input trigger attributes', async () => { - const inputAttributes = [ - ['aria-invalid', 'false'], - ['role', 'combobox'], - ['aria-label', 'Date'], - ['inputmode', 'numeric'], - ]; - - for (const [attr, value] of inputAttributes) { - await expect(inputTrigger).toHaveAttribute(attr, value); - } - }); + await test.step('Reopen datepicker with Space', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await expect(locators.popper(page)).toBeFocused(); + }); - // Triggering the date picker - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - await datePickerTrigger.first().click(); + await test.step('Navigate to prev button and change month', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + const initialTitle = await locators.title(page).textContent(); - await test.step('Verify popper attributes', async () => { - const popperAttributes = [ - ['tabindex', '0'], - ['role', 'dialog'], - ['data-popper-placement', 'bottom-start'], - ]; + await page.keyboard.press('Enter'); + const titleAfterFirstEnter = await locators.title(page).textContent(); + expect(titleAfterFirstEnter).not.toBe(initialTitle); + await expect(locators.title(page)).not.toHaveText(initialTitle!); - for (const [attr, value] of popperAttributes) { - await expect(popper).toHaveAttribute(attr, value); - } - }); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); - await test.step('Verify popper header attributes', async () => { - const headerButtons = [ - { selector: '[data-ui-name="DatePicker.Prev"]', ariaLabel: 'Previous month' }, - { selector: '[data-ui-name="DatePicker.Next"]', ariaLabel: 'Next month' }, - ]; + await page.keyboard.press('Enter'); + const titleAfterSecondEnter = await locators.title(page).textContent(); + expect(titleAfterSecondEnter).toBe(initialTitle); + }); - for (const { selector, ariaLabel } of headerButtons) { - const button = page.locator(selector); - await expect(button).toHaveAttribute('type', 'button'); - await expect(button).toHaveAttribute('aria-label', ariaLabel); - } + await test.step('Verify month changes by Space press', async () => { + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - await expect(headTitle).toHaveAttribute('aria-live', 'polite'); - }); + const initialTitle = await locators.title(page).textContent(); - const weekDaysAttributes = [{ name: 'role', value: 'row' }]; - - const daysOfWeek = [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ]; - - await test.step('Verify popper header attributes', async () => { - const headerLocators = [ - { - locator: '[data-ui-name="DatePicker.Prev"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Previous month'], - ], - }, - { locator: '[data-ui-name="DatePicker.Title"]', attrs: [['aria-live', 'polite']] }, - { - locator: '[data-ui-name="DatePicker.Next"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Next month'], - ], - }, - ]; - - for (const { locator, attrs } of headerLocators) { - const element = page.locator(locator); - for (const [attr, value] of attrs) { - await expect(element).toHaveAttribute(attr, value); - } - } - }); + await page.keyboard.press('Space'); + const titleAfterFirstEnter = await locators.title(page).textContent(); + expect(titleAfterFirstEnter).not.toBe(initialTitle); + await expect(locators.title(page)).not.toHaveText(initialTitle!); + }); - await test.step('Verify calendar attributes', async () => { - const calendar = page.locator('[data-ui-name="DatePicker.Calendar"]'); - await expect(calendar).toHaveAttribute('tabindex', '0'); - await expect(calendar).toHaveAttribute('role', 'grid'); - await expect(calendar).toHaveAttribute('disabled', ''); - }); + await test.step('Navigate to calendar and today button', async () => { + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.calendar(page)).toBeFocused(); - await test.step('Verify weekdays attributes', async () => { - const weekDaysRow = page.locator('[data-ui-name="CalendarWeekDays"]'); - await expect(weekDaysRow).toHaveAttribute('role', 'row'); - - const weekDays = weekDaysRow.locator('[data-ui-name="CalendarWeekDays.Unit"]'); - const daysOfWeek = [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ]; - - for (const [i, dayName] of daysOfWeek.entries()) { - const day = weekDays.nth(i); - await expect(day).toHaveAttribute('role', 'columnheader'); - await expect(day).toHaveAttribute('aria-label', dayName); - - const dayText = (await day.textContent())?.trim(); - expect(dayText).toBe(dayName.slice(0, 3)); - } - }); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Today')).toBeFocused(); + }); - await test.step('Verify days attributes', async () => { - const cells = page.locator('[role="gridcell"]'); - const cellCount = await cells.count(); - - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; - - const dayAttributes = [ - ['role', 'gridcell'], - ['aria-colindex'], - ['aria-rowindex'], - ['aria-selected', 'false'], - ['aria-hidden', 'false'], - ]; + await test.step('Navigate in calendar and select date', async () => { + await page.keyboard.press('ArrowUp'); + await expect(highlightedCell).toBeVisible(); - for (const [attr, value] of dayAttributes) { - if (value !== undefined) { - await expect(cell).toHaveAttribute(attr, value); - } else { - await expect(cell).toHaveAttribute(attr); - } - } + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - const date = new Date(ariaLabel); - const isCurrentMonth = date.getMonth() === 5; // June + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); - const hasDisabled = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('Space'); - if (isCurrentMonth) { - expect(hasDisabled).toBe(false); - } else { - expect(hasDisabled).toBe(true); - } - expect(ariaDisabled).toBe('false'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + const newValue2 = await input.inputValue(); + expect(newValue2).not.toBe(newValue); + }); - const text = (await cell.textContent())?.trim(); - expect(text).not.toBe(''); - } - }); - }); + await test.step('Select today by Enter on Today button', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Today')).toBeFocused(); + const newValue2 = await input.inputValue(); - test('Verify datepicker with custom days styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/custom_day_test.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePickerTrigger = page.locator('[data-ui-name="DatePicker.Trigger"]'); - const cells = page.locator('[role="gridcell"]'); - const selectedCell = page.locator( - '[data-ui-name="CalendarDays.Unit"][class*="__startSelected_"][class*="__endSelected_"]', - ); - - // Helper function to check style properties - const checkStyle = async (element: any, expectedStyles: any) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await test.step('Verify trigger margins', async () => { - await datePickerTrigger.first().click(); - await checkStyle(datePickerTrigger.first(), { marginTop: '8px' }); - }); + await expect(locators.popper(page)).not.toBeVisible(); - await test.step('Verify hover disabled date', async () => { - await checkStyle(cells.first(), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', + const newValue3 = await input.inputValue(); + expect(newValue3).not.toBe(newValue2); }); - }); - await test.step('Verify style of available date', async () => { - await checkStyle(cells.nth(10), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }); - }); + await test.step('Select today by Space on Today button', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await page.keyboard.press('ArrowDown'); + const newValue2 = await input.inputValue(); - await test.step('Verify hover style of available date', async () => { - await datePickerTrigger.first().click(); - page.locator('input[data-ui-name="DatePicker.Trigger"]').fill('05.05.2024'); - await datePickerTrigger.first().click(); - await page.waitForTimeout(300); - }); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Today')).toBeFocused(); - await test.step('Verify style of selected date', async () => { - await checkStyle(selectedCell, { - color: 'rgb(255, 255, 255)', - backgroundColor: 'rgb(43, 179, 255)', - margin: '4px 0px 0px', - width: '32px', + await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + + await expect(locators.popper(page)).not.toBeVisible(); + const newValue3 = await input.inputValue(); + expect(newValue3).not.toBe(newValue2); }); }); }); - test('Verify custom days can be selected by the mouse', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/custom_day_test.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + test.describe('DayPicker with custom days', () => { + test('Verify custom days roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/custom_day_test.tsx', 'en'); + + await test.step('Verify trigger SVG attributes', async () => { + const svg = locators.datePickerTrigger(page).locator('svg'); + const svgAttributes = [ + ['tabindex', '-1'], + ['aria-hidden', 'true'], + ['width', '16'], + ['height', '16'], + ]; - await page.setContent(htmlContent); + for (const [attr, value] of svgAttributes) { + await expect(svg).toHaveAttribute(attr, value); + } + }); - const datePicker = page.locator('[data-ui-name="DatePicker.Trigger"]'); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DatePicker.Next"]'); - const cells = page.locator('[role="gridcell"]'); + const triggerAttributes = [{ name: 'aria-label', value: 'Date field' }]; - const initialValue = await input.inputValue(); + await test.step('Verify trigger attributes', async () => { + for (const { name, value } of triggerAttributes) { + await expect(locators.datePickerTrigger(page, 0)).toHaveAttribute(name, value); + } + }); - await test.step('Open and close datepicker by clicking trigger', async () => { - await datePicker.first().click(); - await expect(popper).toBeVisible(); + const inputTrigger = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + await test.step('Verify input trigger attributes', async () => { + const inputAttributes = [ + ['aria-invalid', 'false'], + ['role', 'combobox'], + ['aria-label', 'Date'], + ['inputmode', 'numeric'], + ]; - await datePicker.first().click(); - await expect(popper).not.toBeVisible(); - }); + for (const [attr, value] of inputAttributes) { + await expect(inputTrigger).toHaveAttribute(attr, value); + } + }); - await test.step('Reopen datepicker', async () => { - await datePicker.first().click(); - await expect(popper).toBeVisible(); - }); + // Triggering the date picker + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Navigate months and verify title change', async () => { - const initialTitle = await headTitle.textContent(); + await test.step('Verify popper attributes', async () => { + const popperAttributes = [ + ['tabindex', '0'], + ['data-popper-placement', 'bottom-start'], + ]; - await headPrev.click(); - await expect(headTitle).not.toHaveText(initialTitle!); + for (const [attr, value] of popperAttributes) { + await expect(locators.popper(page)).toHaveAttribute(attr, value); + } + }); - await headNext.click(); - await expect(headTitle).toHaveText(initialTitle!); - }); + await test.step('Verify title attributes', async () => { + await expect(locators.title(page)).toHaveAttribute('aria-live', 'polite'); + }); - await test.step('Select a day and verify input value changes', async () => { - await cells.nth(10).click(); - await expect(popper).not.toBeVisible(); + await test.step('Verify calendar attributes', async () => { + await expect(locators.calendar(page)).toHaveAttribute('tabindex', '0'); + await expect(locators.calendar(page)).toHaveAttribute('disabled', ''); + }); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); - }); - }); + await test.step('Verify weekdays attributes', async () => { + await expect(locators.weekDaysRow(page)).toHaveAttribute('role', 'row'); + + const weekDays = locators.weekDaysRow(page).locator('[data-ui-name="CalendarWeekDays.Unit"]'); + const daysOfWeek = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; - test('Verify custom days by keyboard interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/custom_day_test.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + for (const [i, dayName] of daysOfWeek.entries()) { + const day = weekDays.nth(i); + await expect(day).toHaveAttribute('role', 'columnheader'); + await expect(day).toHaveAttribute('aria-label', dayName); - await page.setContent(htmlContent); + const dayText = (await day.textContent())?.trim(); + expect(dayText).toBe(dayName.slice(0, 3)); + } + }); - const datePicker = page.locator('[data-ui-name="DatePicker.Trigger"]').first(); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DatePicker.Next"]'); - const calendar = page.locator('[data-ui-name="DatePicker.Calendar"]'); - const highlightedCell = page.locator( - '[data-ui-name="CalendarDays.Unit"][class*="highlighted"]', - ); + await test.step('Verify days attributes', async () => { + const cellCount = await locators.cells(page).count(); + + for (let i = 0; i < cellCount; i++) { + const cell = locators.cells(page).nth(i); + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; + + const dayAttributes = [ + ['aria-colindex'], + ['aria-rowindex'], + ['aria-selected', 'false'], + ['aria-hidden', 'false'], + ]; + + for (const [attr, value] of dayAttributes) { + if (value !== undefined) { + await expect(cell).toHaveAttribute(attr, value); + } else { + await expect(cell).toHaveAttribute(attr); + } + } - const initialValue = await input.inputValue(); + const date = new Date(ariaLabel); + const isCurrentMonth = date.getMonth() === 5; // June - await test.step('Open datepicker with Enter key', async () => { - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await expect(popper).toBeVisible(); - await expect(datePicker).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); + const hasDisabled = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - await test.step('Close datepicker with Escape key', async () => { - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); - await expect(input).toBeFocused(); - }); + if (isCurrentMonth) { + expect(hasDisabled).toBe(false); + } else { + expect(hasDisabled).toBe(true); + } + expect(ariaDisabled).toBe('false'); - await test.step('Reopen datepicker with Space key', async () => { - await page.keyboard.press('Space'); - await expect(popper).toBeVisible(); - await expect(datePicker).not.toBeFocused(); - await expect(popper).toBeFocused(); + const text = (await cell.textContent())?.trim(); + expect(text).not.toBe(''); + } + }); }); - const initialTitle = await headTitle.textContent(); - await test.step('Navigate to previous month and validate title change', async () => { - await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - await headPrev.hover(); - await page.keyboard.press('Enter'); // Space doesn't work — bug - const titleAfterFirstEnter = await headTitle.textContent(); - expect(titleAfterFirstEnter).not.toBe(initialTitle); - await expect(headTitle).not.toHaveText(initialTitle!); - }); + test('Verify custom days can be selected by the mouse', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/custom_day_test.tsx', 'en'); - await test.step('Navigate to next month and validate title restored', async () => { - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + const initialValue = await input.inputValue(); - await page.keyboard.press('Enter'); // Space doesn't work — bug - const titleAfterSecondEnter = await headTitle.textContent(); - expect(titleAfterSecondEnter).toBe(initialTitle); - }); + await test.step('Open datepicker popper by click', async () => { + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + }); - await test.step('Navigate to calendar and today button', async () => { - await page.keyboard.press('Shift+Tab'); - await expect(headPrev).toBeFocused(); + await test.step('Navigate months and verify title change', async () => { + const initialTitle = await locators.title(page).textContent(); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(calendar).toBeFocused(); + await locators.button(page, 'Previous month').click(); + await expect(locators.title(page)).not.toHaveText(initialTitle!); - await page.keyboard.press('Tab'); - await expect(popper).toBeFocused(); + await locators.button(page, 'next month').click(); + await expect(locators.title(page)).toHaveText(initialTitle!); + }); - await page.keyboard.press('Shift+Tab'); - await expect(headNext).toBeFocused(); + await test.step('Select a day and verify input value changes', async () => { + await locators.cells(page, 10).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); + }); }); - await test.step('Navigate in calendar and select highlighted date', async () => { - await page.keyboard.press('ArrowDown'); - await expect(highlightedCell).toBeVisible(); + test('Verify custom days by keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/custom_day_test.tsx', 'en'); - const activeElementHandle = await page.evaluateHandle(() => document.activeElement); - const isFocusedElementHighlighted = await highlightedCell.evaluate( - (el, active) => el === active, - activeElementHandle, + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + const highlightedCell = page.locator( + '[data-ui-name="CalendarDays.Unit"][class*="highlighted"]', ); - expect(isFocusedElementHighlighted).toBe(true); - await page.keyboard.press('Enter'); - await expect(popper).not.toBeVisible(); + const initialValue = await input.inputValue(); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); - }); + await test.step('Open datepicker with Enter key', async () => { + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await expect(locators.datePickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); - await test.step('Select another date after reopening', async () => { - await page.keyboard.press('Enter'); + await test.step('Close datepicker with Escape key', async () => { + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + await expect(input).toBeFocused(); + }); - const newValue = await input.inputValue(); + await test.step('Reopen datepicker with Space key', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('Space'); - await expect(popper).not.toBeVisible(); + await expect(locators.datePickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); + const initialTitle = await locators.title(page).textContent(); + + await test.step('Navigate to previous month and validate title change', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + await locators.button(page, 'Previous month').hover(); + await page.keyboard.press('Enter'); // Space doesn't work — bug + const titleAfterFirstEnter = await locators.title(page).textContent(); + expect(titleAfterFirstEnter).not.toBe(initialTitle); + await expect(locators.title(page)).not.toHaveText(initialTitle!); + }); - const newValue2 = await input.inputValue(); - expect(newValue2).not.toBe(newValue); - }); - }); -}); + await test.step('Navigate to next month and validate title restored', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); -test.describe('DayPikcer trigger and popper', () => { - test('Verify mouse interactions when component uses expanded trigger and popper', async ({ - page, - }) => { - const standPath = 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await page.keyboard.press('Enter'); // Space doesn't work — bug + const titleAfterSecondEnter = await locators.title(page).textContent(); + expect(titleAfterSecondEnter).toBe(initialTitle); + }); - await page.setContent(htmlContent); + await test.step('Navigate to calendar and today button', async () => { + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); - const datePicker = page.locator('[data-ui-name="DatePicker.Trigger"]').first(); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DatePicker.Next"]'); - const cells = page.locator('[role="gridcell"]'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.calendar(page)).toBeFocused(); - const initialValue = await input.inputValue(); + await page.keyboard.press('Tab'); + await expect(locators.popper(page)).toBeFocused(); - await test.step('Toggle popper visibility with click', async () => { - await datePicker.click(); - await expect(popper).toBeVisible(); + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + }); - await datePicker.click(); - await expect(popper).not.toBeVisible(); - }); + await test.step('Navigate in calendar and select highlighted date', async () => { + await page.keyboard.press('ArrowDown'); + await expect(highlightedCell).toBeVisible(); - await test.step('Fill input manually and open calendar', async () => { - await input.fill('04042022'); - await datePicker.click(); - await expect(page).toHaveScreenshot(); - }); + const activeElementHandle = await page.evaluateHandle(() => document.activeElement); + const isFocusedElementHighlighted = await highlightedCell.evaluate( + (el, active) => el === active, + activeElementHandle, + ); + expect(isFocusedElementHighlighted).toBe(true); - await test.step('Navigate months and validate title change', async () => { - const initialTitle = await headTitle.textContent(); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await headPrev.click(); - await expect(headTitle).not.toHaveText(initialTitle!); + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); + }); - await headNext.click(); - await expect(headTitle).toHaveText(initialTitle!); - }); + await test.step('Select another date after reopening', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + + const newValue = await input.inputValue(); - await test.step('Select a date and validate input value change', async () => { - await cells.nth(10).click(); - await expect(popper).not.toBeVisible(); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); + const newValue2 = await input.inputValue(); + expect(newValue2).not.toBe(newValue); + }); }); }); - test('Verify keyboard interactions when component uses expanded trigger and popper', async ({ - page, - }) => { - const standPath = 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + test.describe('DayPikcer trigger and popper', () => { + test('Verify mouse interactions when component uses expanded trigger and popper', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx', 'en'); - await page.setContent(htmlContent); + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + const initialValue = await input.inputValue(); - const datePicker = page.locator('[data-ui-name="DatePicker.Trigger"]').first(); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DatePicker.Next"]'); - const todayButton = page.locator('[data-ui-name="Button"]'); - const calendar = page.locator('[data-ui-name="DatePicker.Calendar"]'); - const highlighted = page.locator('[data-ui-name="CalendarDays.Unit"][class*="highlighted"]'); + await test.step('Navigate months and validate title change', async () => { + await input.fill('04042022'); + await locators.datePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - const initialValue = await input.inputValue(); + const initialTitle = await locators.title(page).textContent(); - await test.step('Focus DatePicker and fill date manually', async () => { - await page.keyboard.press('Tab'); - await input.fill('04042022'); - }); + await locators.button(page, 'Previous month').click(); + await expect(locators.title(page)).not.toHaveText(initialTitle!); - await test.step('Open popper with Enter key and check focus', async () => { - await page.keyboard.press('Enter'); - await expect(popper).toBeVisible(); - await expect(datePicker).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); + await locators.button(page, 'Next month').click(); + await expect(locators.title(page)).toHaveText(initialTitle!); + }); - await test.step('Close popper with Escape key and check focus', async () => { - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); - await expect(input).toBeFocused(); - }); + await test.step('Select a date and validate input value change', async () => { + await locators.cells(page, 10).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await test.step('Reopen popper with Space key and check focus', async () => { - await page.keyboard.press('Space'); - await expect(popper).toBeVisible(); - await expect(datePicker).not.toBeFocused(); - await expect(popper).toBeFocused(); + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); + }); }); - const initialTitle = await headTitle.textContent(); - await test.step('Navigate to previous month and validate title change', async () => { - await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - await headPrev.hover(); - await page.keyboard.press('Enter'); // space doesn't work - bug - const titleAfterFirstEnter = await headTitle.textContent(); - expect(titleAfterFirstEnter).not.toBe(initialTitle); - await expect(headTitle).not.toHaveText(initialTitle!); - }); + test('Verify keyboard interactions when component uses expanded trigger and popper', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/trigger_and_popper.tsx', 'en'); - await test.step('Navigate to next month and validate title reset', async () => { - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); - await page.keyboard.press('Enter'); // space doesn't work - bug - const titleAfterSecondEnter = await headTitle.textContent(); - expect(titleAfterSecondEnter).toBe(initialTitle); - }); + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + const highlighted = page.locator('[data-ui-name="CalendarDays.Unit"][class*="highlighted"]'); + const initialValue = await input.inputValue(); - await test.step('Navigate to calendar and today button', async () => { - await page.keyboard.press('Shift+Tab'); - await expect(headPrev).toBeFocused(); + await test.step('Focus DatePicker and fill date manually', async () => { + await page.keyboard.press('Tab'); + await input.fill('04042022'); + }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(calendar).toBeFocused(); + await test.step('Open popper with Enter key and check focus', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await expect(locators.datePickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); - await page.keyboard.press('Tab'); - await expect(todayButton).toBeFocused(); - await expect(page).toHaveScreenshot(); + await test.step('Close popper with Escape key and check focus', async () => { + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + await expect(input).toBeFocused(); + }); - await page.keyboard.press('Shift+Tab'); - await expect(calendar).toBeFocused(); - }); + await test.step('Reopen popper with Space key and check focus', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await expect(locators.datePickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); + const initialTitle = await locators.title(page).textContent(); + + await test.step('Navigate to previous month and validate title change', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + await locators.button(page, 'Previous month').hover(); + await page.keyboard.press('Space'); + const titleAfterFirstEnter = await locators.title(page).textContent(); + expect(titleAfterFirstEnter).not.toBe(initialTitle); + await expect(locators.title(page)).not.toHaveText(initialTitle!); + }); - await test.step('Move selection inside calendar and validate highlighting', async () => { - await page.keyboard.press('ArrowDown'); - await expect(highlighted).toBeVisible(); + await test.step('Navigate to next month and validate title reset', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + await page.keyboard.press('Enter'); + const titleAfterSecondEnter = await locators.title(page).textContent(); + expect(titleAfterSecondEnter).toBe(initialTitle); + }); - const activeElementHandle = await page.evaluateHandle(() => document.activeElement); - const isFocusedElementHighlighted = await highlighted.evaluate( - (el, active) => el === active, - activeElementHandle, - ); - expect(isFocusedElementHighlighted).toBe(true); - }); + await test.step('Navigate to calendar and today button', async () => { + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); - await test.step('Select day with Enter key and validate input value change', async () => { - await page.keyboard.press('Enter'); - await expect(popper).not.toBeVisible(); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.calendar(page)).toBeFocused(); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); - }); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Today')).toBeFocused(); - await test.step('Quick navigation and selection with keyboard', async () => { - await page.keyboard.press('Enter'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - const newValue = await input.inputValue(); - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('Space'); + await page.keyboard.press('Shift+Tab'); + await expect(locators.calendar(page)).toBeFocused(); + }); - await expect(popper).not.toBeVisible(); - const newValue2 = await input.inputValue(); - expect(newValue2).not.toBe(newValue); - }); - }); -}); + await test.step('Move selection inside calendar and validate highlighting', async () => { + await page.keyboard.press('ArrowDown'); + await expect(highlighted).toBeVisible(); -test.describe('Disabled dates and Validation', () => { - test('Verify validation tooltip', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/disabled_dates.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePicker = page.locator('input[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const tooltip = page.getByRole('tooltip', { name: 'January 1 of this year is off' }); - - await page.keyboard.press('Tab'); - await page.keyboard.type('06'); - await page.keyboard.type('20'); - await expect(datePicker).toHaveAttribute('aria-invalid', 'false'); - - await page.keyboard.type('7875'); - await page.waitForTimeout(250); - await expect(datePicker).toHaveAttribute('aria-invalid', 'true'); - await expect(datePicker).toHaveAttribute('aria-haspopup', 'true'); - - await page.keyboard.press('Backspace'); - await page.keyboard.type('24'); - await expect(datePicker).toHaveAttribute('aria-invalid', 'true'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(50); - await expect(tooltip).toBeVisible(); - await expect(popper).toBeVisible(); - - await page.keyboard.press('Escape'); - await expect(tooltip).toBeVisible(); - await expect(popper).not.toBeVisible(); - - await page.keyboard.press('Escape'); // bug - await expect(tooltip).toBeVisible(); - await expect(datePicker).toHaveAttribute('aria-invalid', 'true'); - }); + const activeElementHandle = await page.evaluateHandle(() => document.activeElement); + const isFocusedElementHighlighted = await highlighted.evaluate( + (el, active) => el === active, + activeElementHandle, + ); + expect(isFocusedElementHighlighted).toBe(true); + }); - test('Verify keyboard interactions when disabled dates and validation tooltip', async ({ - page, - }) => { - const standPath = 'stories/components/date-picker/docs/examples/disabled_dates.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await test.step('Select day with Enter key and validate input value change', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await page.setContent(htmlContent); + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); + }); - const datePicker = page.locator('[data-ui-name="DatePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DatePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DatePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DatePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DatePicker.Next"]'); - const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + await test.step('Quick navigation and selection with keyboard', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Navigate to date picker and fill the input with a date', async () => { - await page.keyboard.press('Tab'); - await input.fill('04/24/2025'); - await page.keyboard.press('Enter'); - }); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + const newValue = await input.inputValue(); + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('Space'); - await test.step('Verify popper visibility and focus', async () => { - await expect(popper).toBeVisible(); - await expect(datePicker.first()).not.toBeFocused(); - await expect(popper).toBeFocused(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + const newValue2 = await input.inputValue(); + expect(newValue2).not.toBe(newValue); + }); }); + }); - await test.step('Close popper with Escape and check input focus', async () => { - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); - await expect(input).toBeFocused(); - }); + test.describe('Disabled dates and Validation', () => { + test('Verify validation tooltip', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + TAG.KEYBOARD], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/disabled_dates.tsx', 'en'); - await test.step('Open popper with Space and check focus', async () => { - await page.keyboard.press('Space'); - await expect(popper).toBeVisible(); - await expect(datePicker.first()).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); - const initialTitle = await headTitle.textContent(); + const tooltip = page.getByRole('tooltip', { name: 'January 1 of this year is off' }); - await test.step('Navigate to previous month and check title', async () => { await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - await page.keyboard.press('Enter'); // space doesn't work - bug! - const titleAfterFirstEnter = await headTitle.textContent(); - expect(titleAfterFirstEnter).not.toBe(initialTitle); - await expect(headTitle).not.toHaveText(initialTitle!); - }); + await page.keyboard.type('06'); + await page.keyboard.type('20'); + await expect(locators.datePickerTrigger(page, 2)).toHaveAttribute('aria-invalid', 'false'); + + await page.keyboard.type('7875'); + await page.waitForTimeout(250); + await expect(locators.datePickerTrigger(page, 2)).toHaveAttribute('aria-invalid', 'true'); + await expect(locators.datePickerTrigger(page, 2)).toHaveAttribute('aria-haspopup', 'true'); + + await page.keyboard.press('Backspace'); + await page.keyboard.type('24'); + await expect(locators.datePickerTrigger(page, 2)).toHaveAttribute('aria-invalid', 'true'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await expect(tooltip).toBeVisible(); - await test.step('Navigate to next month and validate title reset', async () => { - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); - await page.keyboard.press('Enter'); // space doesn't work - bug! - const titleAfterSecondEnter = await headTitle.textContent(); - expect(titleAfterSecondEnter).toBe(initialTitle); - }); + await page.keyboard.press('Escape'); + await expect(tooltip).toBeVisible(); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); - await test.step('Navigate between prev and next month with Tab and Shift+Tab', async () => { - await page.keyboard.press('Shift+Tab'); - await expect(headPrev).toBeFocused(); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page.locator('[data-ui-name="DatePicker.Calendar"]')).toBeFocused(); - await page.keyboard.press('Tab'); - await page.keyboard.press('Shift+Tab'); - await expect(headNext).toBeFocused(); + await page.keyboard.press('Escape'); // bug + await expect(tooltip).toBeVisible(); + await expect(locators.datePickerTrigger(page, 2)).toHaveAttribute('aria-invalid', 'true'); }); - await test.step('Navigate down in the calendar and verify highlighted date', async () => { - await page.keyboard.press('ArrowDown'); - const highlighted = page.locator('[data-ui-name="CalendarDays.Unit"][class*="highlighted"]'); - await expect(highlighted).toBeVisible(); - }); - }); -}); + test('Verify keyboard interactions when disabled dates and validation tooltip', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/disabled_dates.tsx', 'en'); -test.describe('Calendar props and date picker', () => { - test('Verify all calendar props work good', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/calendar_props.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - await page.keyboard.press('Tab'); - await page.keyboard.type('03032025'); - - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); - }); + const input = page.locator('input[data-ui-name="DatePicker.Trigger"]'); + + await test.step('Navigate to date picker and fill the input with a date', async () => { + await page.keyboard.press('Tab'); + await input.fill('04/24/2025'); + await page.keyboard.press('Enter'); + }); + + await test.step('Verify popper visibility and focus', async () => { + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + + await expect(locators.datePickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); + + await test.step('Close popper with Escape and check input focus', async () => { + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + await expect(input).toBeFocused(); + }); + + await test.step('Open popper with Space and check focus', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - test('Verify all date picker props work good', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/date-picker-props.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await page.keyboard.press('Tab'); - const prevButton = page.locator('[data-ui-name="DatePicker.Prev"]'); - await prevButton.hover(); - await expect(page).toHaveScreenshot(); + await expect(locators.datePickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); + const initialTitle = await locators.title(page).textContent(); + + await test.step('Navigate to previous month and check title', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + await page.keyboard.press('Enter'); + const titleAfterFirstEnter = await locators.title(page).textContent(); + expect(titleAfterFirstEnter).not.toBe(initialTitle); + await expect(locators.title(page)).not.toHaveText(initialTitle!); + }); + + await test.step('Navigate to next month and validate title reset', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + await page.keyboard.press('Space'); + const titleAfterSecondEnter = await locators.title(page).textContent(); + expect(titleAfterSecondEnter).toBe(initialTitle); + }); + + await test.step('Navigate between prev and next month with Tab and Shift+Tab', async () => { + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page.locator('[data-ui-name="DatePicker.Calendar"]')).toBeFocused(); + await page.keyboard.press('Tab'); + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + }); + + await test.step('Navigate down in the calendar and verify highlighted date', async () => { + await page.keyboard.press('ArrowDown'); + const highlighted = page.locator('[data-ui-name="CalendarDays.Unit"][class*="highlighted"]'); + await expect(highlighted).toBeVisible(); + }); + }); }); }); diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-chromium-linux.png new file mode 100644 index 0000000000..ed111deb76 Binary files /dev/null and b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-chromium-linux.png new file mode 100644 index 0000000000..2fb496f0d3 Binary files /dev/null and b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png new file mode 100644 index 0000000000..f815debbf5 Binary files /dev/null and b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png new file mode 100644 index 0000000000..c0028f1973 Binary files /dev/null and b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-Date-Picker-Trigger-Verify-trigger-states-when-entering-date-manually-4-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPicker-with-today-button-Verify-datepicker-with-Today-button-styles-4-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-mouse-inte-c8c86-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPikcer-trigger-and-popper-Verify-mo-ed14f-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-mouse-inte-c8c86-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPikcer-trigger-and-popper-Verify-mo-ed14f-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-mouse-inte-c8c86-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPikcer-trigger-and-popper-Verify-mo-ed14f-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-mouse-inte-c8c86-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPikcer-trigger-and-popper-Verify-mo-ed14f-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-mouse-inte-c8c86-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPikcer-trigger-and-popper-Verify-mo-ed14f-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-mouse-inte-c8c86-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/-visual-DayPikcer-trigger-and-popper-Verify-mo-ed14f-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-chromium-linux.png deleted file mode 100644 index 2740fcf94d..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-calendar-props-work-good-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-chromium-linux.png deleted file mode 100644 index 5c1cf2a249..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Calendar-props-and-date-picker-Verify-all-date-picker-props-work-good-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png deleted file mode 100644 index 1c09b9687b..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png deleted file mode 100644 index 91604223dd..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/Date-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png deleted file mode 100644 index fa7d5d4f72..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png deleted file mode 100644 index 31b7e0002d..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-firefox-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png b/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png deleted file mode 100644 index c17ca474d6..0000000000 Binary files a/semcore/date-picker/__tests__/date-picker.browser-test.tsx-snapshots/DayPikcer-trigger-and-popper-Verify-keyboard-i-8e215-en-component-uses-expanded-trigger-and-popper-1-webkit-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx index a2e27d57a9..71301c20b5 100644 --- a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx +++ b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx @@ -1,709 +1,662 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, test } from '@semcore/testing-utils/playwright'; +import type { Page } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; + +import { formatAriaLabelToInputValue } from './utils'; + +export const locators = { + + button: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('button', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + + option: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('option', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + + dateRangeComparatorTrigger: (page: Page, index?: number) => { + const base = page.locator('[data-ui-name="DateRangeComparator.Trigger"]'); + return typeof index === 'number' ? base.nth(index) : base; + }, + calendar: (page: Page) => page.locator('[data-ui-name="DateRangeComparator.Calendar"]'), + weekDaysRow: (page: Page) => page.locator('[data-ui-name="CalendarWeekDays"]'), + divider: (page: Page) => page.locator('[data-ui-name="Divider"]'), + cells: (page: Page, index?: number) => { + const base = page.getByRole('gridcell'); + return typeof index === 'number' ? base.nth(index) : base; + }, + dateRangeHeader: (page: Page) => page.locator('[data-ui-name="DateRangeComparator.Header"]'), + + popper: (page: Page) => page.getByRole('dialog'), + title: (page: Page) => page.locator('[data-ui-name="DateRangeComparator.Title"]'), + period: (page: Page) => page.locator('[data-ui-name="DateRangeComparator.Periods.Options"]'), + + inputValues: (page: Page) => page.locator('input[data-ui-name="DateRangeComparator.ValueDateRange"]'), + compareValues: (page: Page) => page.locator( + 'input[data-ui-name="DateRangeComparator.CompareDateRange"]'), + +}; + +/* ===================================================== +@visual +Visual states, hover and focus styles, paddings, margins, and snapshots. +===================================================== */ +test.describe(`${TAG.VISUAL}`, () => { + test.describe('DateRangeComparator range', () => { + test('Verify date range comparator styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); + + const selectedCell = page.locator('[data-ui-name="CalendarDays.Unit"][class*="Selected"]'); + + // Helper to check multiple style properties + const checkStyle = async (element: any, expectedStyles: any) => { + for (const [property, expectedValue] of Object.entries(expectedStyles)) { + const actualValue = await element.evaluate( + (el: any, property: any) => getComputedStyle(el)[property], + property, + ); + expect(actualValue).toBe(expectedValue); + } + }; -test.describe('DateRangeComparator range', () => { - test('Verify roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePickerTrigger = page - .locator('button[data-ui-name="DateRangeComparator.Trigger"]') - .first(); - const triggerAttributes = [ - { name: 'tabindex', value: '0' }, - { name: 'aria-haspopup', value: 'dialog' }, - { name: 'role', value: 'button' }, - { name: 'type', value: 'button' }, - ]; - - await test.step('Verify trigger attributes', async () => { - for (const { name, value } of triggerAttributes) { - await expect(datePickerTrigger).toHaveAttribute(name, value); - } - }); + await locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await test.step('Verify trigger svg attributes', async () => { - const svg = datePickerTrigger.locator('svg'); - const svgAttributes = [ - { name: 'tabindex', value: '-1' }, - { name: 'aria-hidden', value: 'true' }, - { name: 'width', value: '16' }, - { name: 'height', value: '16' }, - ]; - for (const { name, value } of svgAttributes) { - await expect(svg).toHaveAttribute(name, value); - } - }); + await test.step('Verify header margins and calendar paddings', async () => { + await checkStyle(locators.dateRangeHeader(page), { padding: '16px' }); + const indicators = page.locator('[data-ui-name="DateRange.Indicator"]'); + const count = await indicators.count(); + for (let i = 0; i < count; i++) { + const calendar = indicators.nth(i); + await expect(calendar).toHaveAttribute('width', '16'); + await expect(calendar).toHaveAttribute('height', '16'); + await checkStyle(calendar, { + paddingLeft: '8px', + paddingRight: '8px', + }); + } + }); - datePickerTrigger.click(); - const popper = page.locator('[data-ui-name="DateRangeComparator.Popper"]'); - const popperAttributes = [ - { name: 'tabindex', value: '0' }, - { name: 'role', value: 'dialog' }, - { name: 'data-popper-placement', value: 'bottom-start' }, - ]; - - await test.step('Verify popper attributes', async () => { - for (const { name, value } of popperAttributes) { - await expect(popper).toHaveAttribute(name, value); - } - }); + await test.step('Verify style of available date', async () => { + await checkStyle(locators.cells(page, 2), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - await test.step('Verify popper inputs attributes', async () => { - const inputAttributes = [ - { - selector: '[data-ui-name="DateRangeComparator.ValueDateRange"]', - ariaLabel: 'Date field', - }, - { - selector: '[data-ui-name="DateRangeComparator.CompareDateRange"]', - ariaLabel: 'Date field', - disabled: '', - }, - ]; + await test.step('Select dates', async () => { + await locators.cells(page, 10).click(); + await locators.cells(page, 1).click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - for (const { selector, ariaLabel, disabled } of inputAttributes) { - const input = page.locator(selector); - await expect(input.first()).toHaveAttribute('aria-label', ariaLabel); - if (disabled) await expect(input.first()).toHaveAttribute('disabled', disabled); - } - - const checkboxAttributes = [ - { - selector: '[data-ui-name="Checkbox.Value"]', - attributes: [ - { name: 'type', value: 'checkbox' }, - { name: 'aria-invalid', value: 'false' }, - ], - }, - ]; + await locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + }); - for (const { selector, attributes } of checkboxAttributes) { - const checkbox = page.locator(selector); - for (const { name, value } of attributes) { - await expect(checkbox).toHaveAttribute(name, value); - } - } + await test.step('Verify style of selected date', async () => { + await checkStyle(selectedCell.nth(0), { + margin: '4px 0px 0px', + width: '32px', + height: '32px', + }); + }); + + await test.step('Verify style for Apply picker button', async () => { + await checkStyle(locators.button(page, 'Apply'), { + color: 'rgb(255, 255, 255)', + backgroundColor: 'rgb(0, 143, 248)', + }); + }); + }); + }); - const inputValues = page.locator('input[data-ui-name="DateRangeComparator.ValueDateRange"]'); - const compareValues = page.locator( - 'input[data-ui-name="DateRangeComparator.CompareDateRange"]', - ); + test.describe('Date Range comparator with advanced use', () => { + test('Verify mouse intearctions and styles of advanced use', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator_advanced_use.tsx', 'en'); - const inputAttributesCommon = [ - { name: 'type', value: 'text' }, - { name: 'inputmode', value: 'numeric' }, - { name: 'aria-invalid', value: 'false' }, - ]; + const from = page.locator('[data-ui-name="DateRangeComparator.ValueDateRange"]').first(); + const to = page.locator('[data-ui-name="DateRangeComparator.CompareDateRange"]').first(); + const toggle = page.locator('[data-ui-name="DateRangeComparator.CompareToggle"]'); - const inputs = [inputValues, compareValues]; + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - for (const locator of inputs) { - const count = await locator.count(); - for (let i = 0; i < count; i++) { - const input = locator.nth(i); - for (const { name, value } of inputAttributesCommon) { - await expect(input).toHaveAttribute(name, value); - } - } - } + await from.click(); + await locators.inputValues(page).first().fill('05052023'); + await locators.inputValues(page).nth(1).fill('05202023'); - const calendars = page.locator('[data-name="Calendar"]'); - const calendarAttributes = [ - { name: 'tabindex', value: '-1' }, - { name: 'aria-hidden', value: 'true' }, - ]; + await toggle.click(); + await to.click(); + await locators.compareValues(page).first().fill('05012023'); + await locators.compareValues(page).nth(1).fill('05182023'); - for (let i = 0; i < (await calendars.count()); i++) { - const calendar = calendars.nth(i); - for (const { name, value } of calendarAttributes) { - await expect(calendar).toHaveAttribute(name, value); - } - } + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await expect(page).toHaveScreenshot(); }); + }); - await test.step('Verify calendar header attributes', async () => { - const headerButtons = [ - { selector: '[data-ui-name="DateRangeComparator.Prev"]', ariaLabel: 'Previous month' }, - { selector: '[data-ui-name="DateRangeComparator.Next"]', ariaLabel: 'Next month' }, - ]; + test.describe('Date range comparator props', () => { + test('Verify all date range comparator props work', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page, browserName }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/date-range-comparator-props.tsx', 'en'); + // if (browserName === 'webkit') test.skip(); // skipped for webkit because of unstable focus outline on the dialog - for (const { selector, ariaLabel } of headerButtons) { - const button = page.locator(selector); - await expect(button).toHaveAttribute('type', 'button'); - await expect(button).toHaveAttribute('aria-label', ariaLabel); - } + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - const headTitle = page.locator('[data-ui-name="DateRangeComparator.Title"]'); - await expect(headTitle.first()).toHaveAttribute('aria-live', 'polite'); - await expect(headTitle.nth(1)).toHaveAttribute('aria-live', 'polite'); + await page.keyboard.press('Escape'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); + + await locators.cells(page, 20).hover(); + await expect(page).toHaveScreenshot(); }); + }); +}); - await test.step('Verify calendar attributes', async () => { - const calendars = page.locator('[data-ui-name="DateRangeComparator.Calendar"]'); - const calendarAttributes = [ - { name: 'role', value: 'grid' }, - { name: 'disabled', value: '' }, +/* ===================================================== +@functional +Keyboard and mouse interactions - no snapshots here. +We verify states, visibility, and attributes. +===================================================== */ +test.describe(`${TAG.FUNCTIONAL}`, () => { + test.describe('DateRangeComparator range', () => { + test('Verify roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); + + const triggerAttributes = [ + { name: 'tabindex', value: '0' }, + { name: 'aria-haspopup', value: 'dialog' }, + { name: 'role', value: 'button' }, + { name: 'type', value: 'button' }, ]; - for (let i = 0; i < (await calendars.count()); i++) { - const calendar = calendars.nth(i); - for (const { name, value } of calendarAttributes) { - await expect(calendar).toHaveAttribute(name, value); + await test.step('Verify trigger attributes', async () => { + for (const { name, value } of triggerAttributes) { + await expect(locators.dateRangeComparatorTrigger(page, 0)).toHaveAttribute(name, value); } + }); - const weekDaysrow = calendar.locator('[data-ui-name="CalendarWeekDays"]'); - await expect(weekDaysrow).toHaveAttribute('role', 'row'); - - const weekDays = calendar.locator('[data-ui-name="CalendarWeekDays.Unit"]'); - const daysOfWeek = [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', + await test.step('Verify trigger svg attributes', async () => { + const svg = locators.dateRangeComparatorTrigger(page, 0).locator('svg'); + const svgAttributes = [ + { name: 'tabindex', value: '-1' }, + { name: 'aria-hidden', value: 'true' }, + { name: 'width', value: '16' }, + { name: 'height', value: '16' }, ]; - - for (let i = 0; i < daysOfWeek.length; i++) { - const day = weekDays.nth(i); - await expect(day).toHaveAttribute('role', 'columnheader'); - await expect(day).toHaveAttribute('aria-label', daysOfWeek[i]); - const dayText = await day.textContent(); - await expect(dayText).toBe(daysOfWeek[i].slice(0, 3)); + for (const { name, value } of svgAttributes) { + await expect(svg).toHaveAttribute(name, value); } + }); - await expect(calendar).toHaveAttribute('tabindex', i === 0 ? '0' : '-1'); - } - }); - - await test.step('Verify days attributes', async () => { - const cells = page.locator('[data-ui-name="CalendarDays.Unit"]'); - const cellCount = await cells.count(); + locators.dateRangeComparatorTrigger(page, 0).click(); + const popperAttributes = [ + { name: 'tabindex', value: '0' }, + { name: 'data-popper-placement', value: 'bottom-start' }, + ]; - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; + await test.step('Verify popper attributes', async () => { + for (const { name, value } of popperAttributes) { + await expect(locators.popper(page)).toHaveAttribute(name, value); + } + }); - await expect(cell).toHaveAttribute('role', 'gridcell'); - await expect(cell).toHaveAttribute('aria-colindex'); - await expect(cell).toHaveAttribute('aria-rowindex'); + await test.step('Verify popper inputs attributes', async () => { + const inputAttributes = [ + { + selector: '[data-ui-name="DateRangeComparator.ValueDateRange"]', + ariaLabel: 'Date field', + }, + { + selector: '[data-ui-name="DateRangeComparator.CompareDateRange"]', + ariaLabel: 'Date field', + disabled: '', + }, + ]; - const date = new Date(ariaLabel); - const month = date.getMonth(); - const isCurrentMonth = month === 5; + for (const { selector, ariaLabel, disabled } of inputAttributes) { + const input = page.locator(selector); + await expect(input.first()).toHaveAttribute('aria-label', ariaLabel); + if (disabled) await expect(input.first()).toHaveAttribute('disabled', disabled); + } - const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + const checkboxAttributes = [ + { + selector: '[data-ui-name="Checkbox.Value"]', + attributes: [ + { name: 'type', value: 'checkbox' }, + { name: 'aria-invalid', value: 'false' }, + ], + }, + ]; - if (isCurrentMonth) { - expect(hasDisabledAttr).toBe(false); - expect(ariaDisabled).toBe('false'); + for (const { selector, attributes } of checkboxAttributes) { + const checkbox = page.locator(selector); + for (const { name, value } of attributes) { + await expect(checkbox).toHaveAttribute(name, value); + } } - const text = await cell.textContent(); - expect(text?.trim()).not.toBe(''); - } - }); - - const period = page.locator('[data-ui-name="DateRangeComparator.Periods.Options"]'); - await test.step('Verify Period attributes', async () => { - await expect(period).toHaveAttribute('role', 'listbox'); - await expect(period).toHaveAttribute('aria-label', 'Presets'); - }); + const inputAttributesCommon = [ + { name: 'type', value: 'text' }, + { name: 'inputmode', value: 'numeric' }, + { name: 'aria-invalid', value: 'false' }, + ]; - const periodButtons = page.locator( - '[data-ui-name="DateRangeComparator.Periods.Options"][data-ui-name="Button"]', - ); - await test.step('Verify Period button attributes', async () => { - const count = await periodButtons.count(); - for (let i = 0; i < count; i++) { - const button = periodButtons.nth(i); - await expect(button).toHaveAttribute('type', 'button'); - await expect(button).toHaveAttribute('role', 'option'); - await expect(button).toHaveAttribute('tabindex', '0'); - } - }); + const inputs = [locators.inputValues(page), locators.compareValues(page)]; - const applyButton = page.locator('[data-ui-name="DateRangeComparator.Apply"]'); - await test.step('Verify Apply button attributes', async () => { - await expect(applyButton).toHaveAttribute('type', 'button'); - }); + for (const locator of inputs) { + const count = await locator.count(); + for (let i = 0; i < count; i++) { + const input = locator.nth(i); + for (const { name, value } of inputAttributesCommon) { + await expect(input).toHaveAttribute(name, value); + } + } + } + }); - const resetButton = page.locator('[data-ui-name="DateRangeComparator.Reset"]'); - await test.step('Verify Reset button attributes', async () => { - await expect(resetButton).toHaveAttribute('type', 'button'); - }); - }); + await test.step('Verify calendar header attributes', async () => { + await expect(locators.title(page).first()).toHaveAttribute('aria-live', 'polite'); + await expect(locators.title(page).nth(1)).toHaveAttribute('aria-live', 'polite'); + }); - test('Verify date range comparator styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const trigger = page.locator('[data-ui-name="DateRangeComparator.Trigger"]'); - const dateRangeHeader = page.locator('[data-ui-name="DateRangeComparator.Header"]'); - const calendars = page.locator('[data-name="Calendar"]'); - const cells = page.locator('[data-ui-name="CalendarDays.Unit"]'); - const applyButton = page.locator('[data-ui-name="DateRangeComparator.Apply"]'); - const selectedCell = page.locator('[data-ui-name="CalendarDays.Unit"][class*="Selected"]'); - - // Helper to check multiple style properties - const checkStyle = async (element: any, expectedStyles: any) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; - - await trigger.click(); - await page.waitForTimeout(300); - - await test.step('Verify header margins and calendar paddings', async () => { - await checkStyle(dateRangeHeader, { padding: '16px' }); - - const count = await calendars.count(); - for (let i = 0; i < count; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('width', '16'); - await expect(calendar).toHaveAttribute('height', '16'); - await checkStyle(calendar, { - paddingLeft: '8px', - paddingRight: '8px', - }); - } - }); + await test.step('Verify calendar attributes', async () => { + const calendarAttributes = [ + { name: 'role', value: 'grid' }, + { name: 'disabled', value: '' }, + ]; - await test.step('Verify style of available date', async () => { - await checkStyle(cells.nth(2), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }); - }); + for (let i = 0; i < (await locators.calendar(page).count()); i++) { + const calendar = locators.calendar(page).nth(i); + for (const { name, value } of calendarAttributes) { + await expect(calendar).toHaveAttribute(name, value); + } - await test.step('Select dates', async () => { - await cells.nth(10).click(); - await cells.nth(11).click(); - await applyButton.click(); - await trigger.click(); - }); + const weekDays = calendar.locator('[data-ui-name="CalendarWeekDays.Unit"]'); + const daysOfWeek = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; + + for (let i = 0; i < daysOfWeek.length; i++) { + const day = weekDays.nth(i); + await expect(day).toHaveAttribute('role', 'columnheader'); + await expect(day).toHaveAttribute('aria-label', daysOfWeek[i]); + const dayText = await day.textContent(); + await expect(dayText).toBe(daysOfWeek[i].slice(0, 3)); + } - await test.step('Verify style of selected date', async () => { - await checkStyle(selectedCell.nth(0), { - margin: '4px 0px 0px', - width: '32px', - height: '32px', + await expect(calendar).toHaveAttribute('tabindex', i === 0 ? '0' : '-1'); + } }); - }); - await test.step('Verify style for Apply picker button', async () => { - await checkStyle(applyButton, { - color: 'rgb(255, 255, 255)', - backgroundColor: 'rgb(0, 143, 248)', - }); - }); - }); + await test.step('Verify days attributes', async () => { + const cells = page.locator('[data-ui-name="CalendarDays.Unit"]'); + const cellCount = await cells.count(); - function formatAriaLabelToInputValue(ariaLabel: string | null): string { - if (!ariaLabel) { - throw new Error('aria-label is null'); - } - const parsedDate = new Date(ariaLabel); - - if (isNaN(parsedDate.getTime())) { - throw new Error(`Invalid aria-label date: ${ariaLabel}`); - } - - const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); - const day = parsedDate.getDate().toString().padStart(2, '0'); - const year = parsedDate.getFullYear().toString(); - - return `${month}/${day}/${year}`; - } - - test('Verify Date comparator range mouse interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePicker = page.locator('[data-ui-name="DateRangeComparator.Trigger"]'); - const popper = page.locator('[data-ui-name="DateRangeComparator.Popper"]'); - const headPrev = page.locator('[data-ui-name="DateRangeComparator.Prev"]'); - const headTitle = page.locator('[data-ui-name="DateRangeComparator.Title"]'); - const headNext = page.locator('[data-ui-name="DateRangeComparator.Next"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const inputFrom = page.locator('input[data-ui-name="DateRangeComparator.ValueDateRange"]'); - const inputTo = page.locator('input[data-ui-name="DateRangeComparator.CompareDateRange"]'); - const toggle = page.locator('[data-ui-name="DateRangeComparator.CompareToggle"]'); - const apply = page.locator('[data-ui-name="DateRangeComparator.Apply"]'); - const reset = page.locator('[data-ui-name="DateRangeComparator.Reset"]'); - const cells = page.locator('[role="gridcell"]'); - - let initialTitle1: string | null = ''; - let initialTitle2: string | null = ''; - let expectedInputValue = ''; - let expectedInputValue22 = ''; - let expectedInputValue50 = ''; - let expectedInputValue55 = ''; - - await test.step('Open and close calendar', async () => { - await datePicker.click(); - await page.waitForTimeout(200); - await expect(popper).toBeVisible(); - await datePicker.click(); - await expect(popper).not.toBeVisible(); - await datePicker.click(); - await page.waitForTimeout(200); - }); + for (let i = 0; i < cellCount; i++) { + const cell = cells.nth(i); + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; - await test.step('Navigate months using header buttons', async () => { - initialTitle1 = await headTitle.first().textContent(); - initialTitle2 = await headTitle.nth(1).textContent(); + await expect(cell).toHaveAttribute('role', 'gridcell'); + await expect(cell).toHaveAttribute('aria-colindex'); + await expect(cell).toHaveAttribute('aria-rowindex'); - await headPrev.click(); - await expect(headTitle.first()).not.toHaveText(initialTitle1!); - await expect(headTitle.nth(1)).not.toHaveText(initialTitle2!); + const date = new Date(ariaLabel); + const month = date.getMonth(); + const isCurrentMonth = month === 5; - await headNext.click(); - await expect(headTitle.first()).toHaveText(initialTitle1!); - await expect(headTitle.nth(1)).toHaveText(initialTitle2!); - }); + const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - await test.step('Select first date in from input', async () => { - await cells.nth(10).click(); - await page.waitForTimeout(50); - const inputValue_1 = await inputFrom.nth(0).inputValue(); - const inputValue_2 = await inputFrom.nth(1).inputValue(); - const calendarAriaLabel = await cells.nth(10).getAttribute('aria-label'); + if (isCurrentMonth) { + expect(hasDisabledAttr).toBe(false); + expect(ariaDisabled).toBe('false'); + } - expectedInputValue = formatAriaLabelToInputValue(calendarAriaLabel); + const text = await cell.textContent(); + expect(text?.trim()).not.toBe(''); + } + }); - await expect(inputValue_1).toBe(expectedInputValue); - await expect(inputValue_2).toBe(''); + await test.step('Verify Period attributes', async () => { + await expect(locators.period(page)).toHaveAttribute('role', 'listbox'); + await expect(locators.period(page)).toHaveAttribute('aria-label', 'Presets'); + }); }); - await test.step('Select second date in from input', async () => { - await expect(popper).toBeVisible(); - await cells.nth(15).click(); - await page.waitForTimeout(50); - const inputValue_2 = await inputFrom.nth(1).inputValue(); - const calendarAriaLabel22 = await cells.nth(15).getAttribute('aria-label'); - - expectedInputValue22 = formatAriaLabelToInputValue(calendarAriaLabel22); - await expect(inputValue_2).toBe(expectedInputValue22); - }); + test('Verify Date comparator range mouse interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); - await test.step('Reset from input values by clicking same cell', async () => { - await expect(popper).toBeVisible(); - await cells.nth(15).click(); - await page.waitForTimeout(100); + const toggle = page.locator('[data-ui-name="DateRangeComparator.CompareToggle"]'); - const inputValue1 = await inputFrom.nth(0).inputValue(); - const inputValue2 = await inputFrom.nth(1).inputValue(); + let initialTitle1: string | null = ''; + let initialTitle2: string | null = ''; + let expectedInputValue = ''; + let expectedInputValue22 = ''; + let expectedInputValue50 = ''; + let expectedInputValue55 = ''; - await expect(inputValue1).toBe(expectedInputValue22); - await expect(inputValue2).toBe(''); - }); + await test.step('Open and close calendar', async () => { + await locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await test.step('Confirm both from inputs set to same date', async () => { - await cells.nth(15).click(); + await locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + ; + await locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + }); - const inputValue1 = await inputFrom.nth(0).inputValue(); - const inputValue2 = await inputFrom.nth(1).inputValue(); + await test.step('Navigate months using header buttons', async () => { + initialTitle1 = await locators.title(page).first().textContent(); + initialTitle2 = await locators.title(page).nth(1).textContent(); - await expect(inputValue1).toBe(expectedInputValue22); - await expect(inputValue2).toBe(expectedInputValue22); - }); + await locators.button(page, 'Previous month').click(); + await expect(locators.title(page).first()).not.toHaveText(initialTitle1!); + await expect(locators.title(page).nth(1)).not.toHaveText(initialTitle2!); - await test.step('Switch to "compare" mode', async () => { - await toggle.click(); - }); + await locators.button(page, 'Next month').click(); + await expect(locators.title(page).first()).toHaveText(initialTitle1!); + await expect(locators.title(page).nth(1)).toHaveText(initialTitle2!); + }); - await test.step('Select first date in to input', async () => { - await cells.nth(50).click(); - await page.waitForTimeout(50); - const inputValue1 = await inputTo.nth(0).inputValue(); - const inputValue2 = await inputTo.nth(1).inputValue(); - const calendarAriaLabel50 = await cells.nth(50).getAttribute('aria-label'); + await test.step('Select first date in from input', async () => { + await locators.cells(page, 10).click(); + await page.waitForTimeout(50); + const inputValue_1 = await locators.inputValues(page).nth(0).inputValue(); + const inputValue_2 = await locators.inputValues(page).nth(1).inputValue(); + const calendarAriaLabel = await locators.cells(page, 10).getAttribute('aria-label'); - expectedInputValue50 = formatAriaLabelToInputValue(calendarAriaLabel50); + expectedInputValue = formatAriaLabelToInputValue(calendarAriaLabel); - await expect(inputValue1).toBe(expectedInputValue50); - await expect(inputValue2).toBe(''); - }); + await expect(inputValue_1).toBe(expectedInputValue); + await expect(inputValue_2).toBe(''); + }); - await test.step('Select second date in to input', async () => { - await cells.nth(55).click(); - await page.waitForTimeout(50); - const inputValue1 = await inputTo.nth(0).inputValue(); - const inputValue2 = await inputTo.nth(1).inputValue(); - const calendarAriaLabel55 = await cells.nth(55).getAttribute('aria-label'); + await test.step('Select second date in from input', async () => { + await locators.cells(page, 15).click(); + await page.waitForTimeout(50); + const inputValue_2 = await locators.inputValues(page).nth(1).inputValue(); + const calendarAriaLabel22 = await locators.cells(page, 15).getAttribute('aria-label'); - expectedInputValue55 = formatAriaLabelToInputValue(calendarAriaLabel55); + expectedInputValue22 = formatAriaLabelToInputValue(calendarAriaLabel22); + await expect(inputValue_2).toBe(expectedInputValue22); + }); - await expect(inputValue1).toBe(expectedInputValue50); - await expect(inputValue2).toBe(expectedInputValue55); - }); + await test.step('Reset from input values by clicking same cell', async () => { + await locators.cells(page, 15).click(); + await page.waitForTimeout(100); - await test.step('Apply selection and close calendar', async () => { - await apply.click(); - await page.waitForTimeout(50); - await expect(popper).not.toBeVisible(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).not.toHaveText( - 'Select date ranges', - ); - }); + const inputValue1 = await locators.inputValues(page).nth(0).inputValue(); + const inputValue2 = await locators.inputValues(page).nth(1).inputValue(); - await test.step('Reset selections', async () => { - await datePicker.click(); - await page.waitForTimeout(200); - await reset.click(); - await expect(popper).not.toBeVisible(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).toHaveText( - 'Select date ranges', - ); - }); + await expect(inputValue1).toBe(expectedInputValue22); + await expect(inputValue2).toBe(''); + }); - await test.step('Open calendar and close with Sange selection', async () => { - await datePicker.click(); - await page.waitForTimeout(200); - await buttons.nth(1).click(); - await expect(popper).toBeVisible(); - await apply.click(); - await expect(popper).not.toBeVisible(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).not.toHaveText( - 'Select date ranges', - ); - }); - }); + await test.step('Confirm both from inputs set to same date', async () => { + await locators.cells(page, 15).click(); - test('Verify Date range comparator keyboard interactions', async ({ page, browserName }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - await page.setContent(await e2eStandToHtml(standPath, 'en')); + const inputValue1 = await locators.inputValues(page).nth(0).inputValue(); + const inputValue2 = await locators.inputValues(page).nth(1).inputValue(); - const getInputValues = async (locator: any) => ({ - from: await locator.nth(0).inputValue(), - to: await locator.nth(1).inputValue(), - }); + await expect(inputValue1).toBe(expectedInputValue22); + await expect(inputValue2).toBe(expectedInputValue22); + }); - const datePicker = page.locator('[data-ui-name="DateRangeComparator.Trigger"]'); - const popper = page.locator('[data-ui-name="DateRangeComparator.Popper"]'); - const headTitle = page.locator('[data-ui-name="DateRangeComparator.Title"]'); - const inputFrom = page.locator('input[data-ui-name="DateRangeComparator.ValueDateRange"]'); - const inputTo = page.locator('input[data-ui-name="DateRangeComparator.CompareDateRange"]'); - const apply = page.locator('[data-ui-name="DateRangeComparator.Apply"]'); - const reset = page.locator('[data-ui-name="DateRangeComparator.Reset"]'); - const headPrev = page.locator('[data-ui-name="DateRangeComparator.Prev"]'); - const headNext = page.locator('[data-ui-name="DateRangeComparator.Next"]'); + await test.step('Switch to "compare" mode', async () => { + await toggle.click(); + }); - if (browserName === 'webkit') return; + await test.step('Select first date in to input', async () => { + await locators.cells(page, 50).click(); + await page.waitForTimeout(50); + const inputValue1 = await locators.compareValues(page).nth(0).inputValue(); + const inputValue2 = await locators.compareValues(page).nth(1).inputValue(); + const calendarAriaLabel50 = await locators.cells(page, 50).getAttribute('aria-label'); - await test.step('Open and close calendar using keyboard', async () => { - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); + expectedInputValue50 = formatAriaLabelToInputValue(calendarAriaLabel50); - await page.keyboard.press('Tab'); - await page.keyboard.type('04042024'); - await page.keyboard.type('04042024'); + await expect(inputValue1).toBe(expectedInputValue50); + await expect(inputValue2).toBe(''); + }); - for (let i = 0; i < 9; i++) await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await expect(popper).not.toBeVisible(); - await expect(datePicker).toBeFocused(); + await test.step('Select second date in to input', async () => { + await locators.cells(page, 55).click(); + await page.waitForTimeout(50); + const inputValue1 = await locators.compareValues(page).nth(0).inputValue(); + const inputValue2 = await locators.compareValues(page).nth(1).inputValue(); + const calendarAriaLabel55 = await locators.cells(page, 55).getAttribute('aria-label'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await expect(popper).toBeVisible(); - await expect(datePicker).not.toBeFocused(); - await expect(popper).toBeFocused(); + expectedInputValue55 = formatAriaLabelToInputValue(calendarAriaLabel55); - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); + await expect(inputValue1).toBe(expectedInputValue50); + await expect(inputValue2).toBe(expectedInputValue55); + }); - await page.keyboard.press('Space'); - await page.waitForTimeout(300); - await expect(popper).toBeVisible(); - }); + await test.step('Apply selection and close calendar', async () => { + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - await test.step('Navigate months backwards and forwards', async () => { - const initial = { - from: await headTitle.first().textContent(), - to: await headTitle.nth(1).textContent(), - }; + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).not.toHaveText( + 'Select date ranges', + ); + }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - await page.keyboard.press('Enter'); + await test.step('Reset selections', async () => { + locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - const changed = { - from: await headTitle.first().textContent(), - to: await headTitle.nth(1).textContent(), - }; + await locators.button(page, 'Reset').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - expect(changed.from).not.toBe(initial.from); - expect(changed.to).not.toBe(initial.to); + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).toHaveText( + 'Select date ranges', + ); + }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); - await page.keyboard.press('Enter'); + await test.step('Open calendar and close with Sange selection', async () => { + locators.dateRangeComparatorTrigger(page, 0).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - const reverted = { - from: await headTitle.first().textContent(), - to: await headTitle.nth(1).textContent(), - }; + await locators.option(page, 'Last 3 months').click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - expect(reverted.from).toBe(initial.from); - expect(reverted.to).toBe(initial.to); + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).not.toHaveText( + 'Select date ranges', + ); + }); }); - await test.step('Select From dates with keyboard', async () => { - const initial = await getInputValues(inputFrom); + test('Verify Date range comparator keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page, browserName }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); + const getInputValues = async (locator: any) => ({ + from: await locator.nth(0).inputValue(), + to: await locator.nth(1).inputValue(), + }); - const unchanged = await getInputValues(inputFrom); - expect(unchanged).toEqual(initial); + // if (browserName === 'webkit') return; - await page.keyboard.press('Space'); - await page.waitForTimeout(50); + await test.step('Open and close calendar using keyboard', async () => { + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - const changed = await getInputValues(inputFrom); - expect(changed.from).not.toBe(initial.from); - expect(changed.to).not.toBe(initial.to); + await page.keyboard.press('Tab'); + await page.keyboard.type('04042024'); + await page.keyboard.type('04042024'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Space'); + for (let i = 0; i < 9; i++) await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + await expect(locators.dateRangeComparatorTrigger(page, 0)).toBeFocused(); - const final = await getInputValues(inputFrom); - expect(final.from).toBe(changed.from); - expect(final.to).not.toBe(initial.to); - }); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await test.step('Switch to Compare mode and select To dates', async () => { - for (let i = 0; i < 3; i++) await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('Space'); - await page.waitForTimeout(200); + await expect(locators.dateRangeComparatorTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); - for (let i = 0; i < 3; i++) await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); + await page.keyboard.press('Escape'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - const initial = await getInputValues(inputTo); - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('ArrowUp'); - await page.keyboard.press('Space'); + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + }); - const mid = await getInputValues(inputTo); - expect(mid.from).not.toBe(initial.from); - expect(mid.to).toBe(initial.to); + await test.step('Navigate months backwards and forwards', async () => { + const initial = { + from: await locators.title(page).first().textContent(), + to: await locators.title(page).nth(1).textContent(), + }; + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + await page.keyboard.press('Enter'); + + const changed = { + from: await locators.title(page).first().textContent(), + to: await locators.title(page).nth(1).textContent(), + }; + + expect(changed.from).not.toBe(initial.from); + expect(changed.to).not.toBe(initial.to); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + await page.keyboard.press('Enter'); + + const reverted = { + from: await locators.title(page).first().textContent(), + to: await locators.title(page).nth(1).textContent(), + }; + + expect(reverted.from).toBe(initial.from); + expect(reverted.to).toBe(initial.to); + }); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Space'); + await test.step('Select From dates with keyboard', async () => { + const initial = await getInputValues(locators.inputValues(page)); - const final = await getInputValues(inputTo); - expect(final.from).toBe(mid.from); - expect(final.to).not.toBe(mid.to); - }); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); - await test.step('Apply and reset selected dates', async () => { - for (let i = 0; i < 6; i++) await page.keyboard.press('Tab'); - await expect(apply).toBeFocused(); - await page.keyboard.press('Enter'); - await expect(popper).not.toBeVisible(); + const unchanged = await getInputValues(locators.inputValues(page)); + expect(unchanged).toEqual(initial); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); + await page.keyboard.press('Space'); + await page.waitForTimeout(50); - for (let i = 0; i < 14; i++) await page.keyboard.press('Tab'); - await expect(reset).toBeFocused(); - await page.keyboard.press('Space'); - await page.waitForTimeout(300); + const changed = await getInputValues(locators.inputValues(page)); + expect(changed.from).not.toBe(initial.from); + expect(changed.to).not.toBe(initial.to); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).toHaveText( - 'Select date ranges', - ); - }); - }); -}); - -test.describe('Date Range comparator with advanced use', () => { - test('Verify mouse intearctions and styles of advanced use', async ({ page }) => { - const standPath = - 'stories/components/date-picker/docs/examples/date_range_comparator_advanced_use.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Space'); - await page.setContent(htmlContent); + const final = await getInputValues(locators.inputValues(page)); + expect(final.from).toBe(changed.from); + expect(final.to).not.toBe(initial.to); + }); - const datePicker = await page.locator('[data-ui-name="DateRangeComparator.Trigger"]'); - const from = page.locator('[data-ui-name="DateRangeComparator.ValueDateRange"]').first(); - const inputFrom = page.locator('input[data-ui-name="DateRangeComparator.ValueDateRange"]'); - const to = page.locator('[data-ui-name="DateRangeComparator.CompareDateRange"]').first(); - const inputTo = page.locator('input[data-ui-name="DateRangeComparator.CompareDateRange"]'); - const toggle = page.locator('[data-ui-name="DateRangeComparator.CompareToggle"]'); - const apply = page.locator('[data-ui-name="DateRangeComparator.Apply"]'); + await test.step('Switch to Compare mode and select To dates', async () => { + for (let i = 0; i < 3; i++) await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(200); + for (let i = 0; i < 3; i++) await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); - await from.click(); - await inputFrom.first().fill('05052023'); - await inputFrom.nth(1).fill('05202023'); + const initial = await getInputValues(locators.compareValues(page)); + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('ArrowUp'); + await page.keyboard.press('Space'); - await toggle.click(); - await to.click(); - await inputTo.first().fill('05012023'); - await inputTo.nth(1).fill('05182023'); + const mid = await getInputValues(locators.compareValues(page)); + expect(mid.from).not.toBe(initial.from); + expect(mid.to).toBe(initial.to); - await apply.click(); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Space'); - await datePicker.click(); - await page.waitForTimeout(300); - await expect(page).toHaveScreenshot(); - }); -}); + const final = await getInputValues(locators.compareValues(page)); + expect(final.from).toBe(mid.from); + expect(final.to).not.toBe(mid.to); + }); -test.describe('Date range comparator props', () => { - test('Verify all date range comparator props work', async ({ page, browserName }) => { - if (browserName === 'webkit') return; // skipped for webkit because of unstable focus outline on the dialog - const standPath = - 'stories/components/date-picker/tests/examples/date-range-comparator-props.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - const apply = page.locator('[data-ui-name="DateRangeComparator.Apply"]'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'visible' }); - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'visible' }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); - - const cells = page.locator('[role="gridcell"]'); - - await cells.nth(20).hover(); - await expect(page).toHaveScreenshot(); + await test.step('Apply and reset selected dates', async () => { + for (let i = 0; i < 6; i++) await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Apply')).toBeFocused(); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + for (let i = 0; i < 14; i++) await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Reset')).toBeFocused(); + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').first()).toHaveText( + 'Select date ranges', + ); + }); + }); }); }); diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-Range-comparator-with-advanced-us-f1256-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-Range-comparator-with-advanced-us-f1256-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-Range-comparator-with-advanced-us-f1256-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-Range-comparator-with-advanced-us-f1256-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-Range-comparator-with-advanced-us-f1256-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-Range-comparator-with-advanced-us-f1256-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-webkit-linux.png new file mode 100644 index 0000000000..1c998f8c7e Binary files /dev/null and b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-1-webkit-linux.png differ diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-firefox-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-webkit-linux.png b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-webkit-linux.png new file mode 100644 index 0000000000..4d79f73b43 Binary files /dev/null and b/semcore/date-picker/__tests__/date-range-comparator.browser-test.tsx-snapshots/-visual-Date-range-comparator-props-Verify-all-date-range-comparator-props-work-2-webkit-linux.png differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx index 40717b3ba6..9124ec6aa0 100644 --- a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx +++ b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx @@ -1,783 +1,745 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, test } from '@semcore/testing-utils/playwright'; +import type { Page } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; + +import { formatAriaLabelToInputValue, checkStyle } from './utils'; + +export const locators = { + + button: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('button', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + option: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('option', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + dateRangePickerTrigger: (page: Page, index?: number) => { + const base = page.locator('[data-ui-name="DateRangePicker.Trigger"]'); + return typeof index === 'number' ? base.nth(index) : base; + }, + calendar: (page: Page) => page.locator('[data-ui-name="DateRangePicker.Calendar"]'), + weekDaysRow: (page: Page) => page.locator('[data-ui-name="CalendarWeekDays"]'), + divider: (page: Page) => page.locator('[data-ui-name="Divider"]'), + cells: (page: Page, index?: number) => { + const base = page.getByRole('gridcell'); + return typeof index === 'number' ? base.nth(index) : base; + }, + dateRangeHeader: (page: Page) => page.locator('[data-ui-name="DateRangePicker.Header"]'), + + popper: (page: Page) => page.getByRole('dialog'), + title: (page: Page) => page.locator('[data-ui-name="DateRangePicker.Title"]'), + period: (page: Page) => page.locator('[data-ui-name="DateRangePicker.Period"]'), +}; + +/* ===================================================== +@visual +Visual states, hover and focus styles, paddings, margins, and snapshots. +===================================================== */ +test.describe(`${TAG.VISUAL}`, () => { + test.describe('Date Range Trigger', () => { + test('Verify trigger states when entering sate manually', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/datepicker.tsx', 'en'); + + const screenshotsClip = (await locators.dateRangePickerTrigger(page, 0).boundingBox())!; + screenshotsClip.x -= 4; + screenshotsClip.y -= 4; + screenshotsClip.width += 8; + screenshotsClip.height += 8; + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.type('052020'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.type('2005292020'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Shift+Tab'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + + await page.keyboard.press('Tab'); + await page.keyboard.press('ArrowRight'); + for (let i = 0; i < 5; i++) await page.keyboard.press('Backspace'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + }); -test.describe('Date Range Trigger', () => { - test('Verify trigger states when entering sate manually', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePicker = await page.locator('[data-ui-name="DateRangePicker.Trigger"]'); - const screenshotsClip = (await datePicker.first().boundingBox())!; - screenshotsClip.x -= 4; - screenshotsClip.y -= 4; - screenshotsClip.width += 8; - screenshotsClip.height += 8; - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.type('052020'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.type('2005292020'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('Shift+Tab'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - - await page.keyboard.press('Tab'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - }); - - test('Verify trigger states and props', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/day-range-trigger.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); - }); -}); - -test.describe('Date range with standart ranges', () => { - test('Verify roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); + test('Verify trigger states and props', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/day-range-trigger.tsx', 'en'); - const datePickerTrigger = page.locator('[data-ui-name="DateRangePicker.Trigger"]').nth(4); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); - await test.step('Verify trigger aria label', async () => { - await expect(datePickerTrigger).toHaveAttribute('aria-label', 'Date field'); - }); + for (let i = 0; i < 5; i++) await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); - await test.step('Verify trigger svg attributes', async () => { - const svgAttributes = [ - ['tabindex', '-1'], - ['aria-hidden', 'true'], - ['width', '16'], - ['height', '16'], - ]; - const svg = datePickerTrigger.locator('svg'); - for (const [attr, value] of svgAttributes) { - await expect(svg).toHaveAttribute(attr, value); - } + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); }); - - const inputTriggr = page.locator('input[data-ui-name="DateRangePicker.Trigger"]'); - - const inputAttributes = [ - { index: 2, label: 'From date' }, - { index: 3, label: 'To Date field' }, - ]; - - for (const { index, label } of inputAttributes) { - await test.step(`Verify ${label} trigger attributes`, async () => { - await expect(inputTriggr.nth(index)).toHaveAttribute('aria-invalid', 'false'); - await expect(inputTriggr.nth(index)).toHaveAttribute('aria-haspopup', 'dialog'); - await expect(inputTriggr.nth(index)).toHaveAttribute('aria-expanded', 'false'); - await expect(inputTriggr.nth(index)).toHaveAttribute('role', 'combobox'); - await expect(inputTriggr.nth(index)).toHaveAttribute('aria-label', label); - await expect(inputTriggr.nth(index)).toHaveAttribute('inputmode', 'numeric'); + }); + test.describe('Date range with standart ranges', () => { + test('Verify date range picker styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx', 'en'); + + await test.step('Verify trigger margins', async () => { + await checkStyle(locators.dateRangePickerTrigger(page, 4), { marginTop: '8px' }); }); - } - datePickerTrigger.click(); - const popper = page.locator('[data-ui-name="DateRangePicker.Popper"]'); + await test.step('Verify svg dimensions', async () => { + const svg = locators.dateRangePickerTrigger(page, 4).locator('svg'); + await checkStyle(svg, { paddingLeft: '8px', paddingRight: '8px' }); + await expect(svg).toHaveAttribute('width', '16'); + await expect(svg).toHaveAttribute('height', '16'); + }); - await test.step('Verify popper attributes', async () => { - const popperAttributes = [ - ['tabindex', '0'], - ['role', 'dialog'], - ['data-popper-placement', 'bottom-start'], - ]; + await test.step('Verify trigger separator padding', async () => { + const separator = page.locator('[data-ui-name="DateRange.RangeSep"]').nth(1); + await checkStyle(separator, { paddingRight: '8px' }); + }); - for (const [attr, value] of popperAttributes) { - await expect(popper).toHaveAttribute(attr, value); - } - }); + await test.step('Enter dates and open popper', async () => { + await page.locator('input[data-ui-name="DateRangePicker.Trigger"]').nth(2).fill('05.04.2025'); + await page.locator('input[data-ui-name="DateRangePicker.Trigger"]').nth(3).fill('05.05.2025'); + await locators.dateRangePickerTrigger(page, 4).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + }); - await test.step('Verify popper header attributes', async () => { - const headerAttributes = [ + const dateStyles = [ { - locator: '[data-ui-name="DateRangePicker.Prev"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Previous month'], - ], + locator: locators.cells(page, 0), + expectedStyles: { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }, }, { - locator: '[data-ui-name="DateRangePicker.Next"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Next month'], - ], + locator: locators.cells(page, 10), + expectedStyles: { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }, }, ]; - for (const { locator, attrs } of headerAttributes) { - const element = page.locator(locator); - for (const [attr, value] of attrs) { - await expect(element).toHaveAttribute(attr, value); - } - } - await expect(page.locator('[data-ui-name="DateRangePicker.Title"]').first()).toHaveAttribute( - 'aria-live', - 'polite', - ); - await expect( - page.locator('[data-ui-name="DateRangePicker.Title"]').nth(1), - ).not.toHaveAttribute('aria-live', ''); - }); - - await test.step('Verify calendar attributes', async () => { - const calendars = page.locator('[data-ui-name="DateRangePicker.Calendar"]'); - const count = await calendars.count(); - - for (let i = 0; i < count; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('role', 'grid'); - await expect(calendar).toHaveAttribute('disabled', ''); + for (const { locator, expectedStyles } of dateStyles) { + await test.step(`Verify style of ${locator === locators.cells(page, 0) ? 'disabled' : 'available' + } date`, async () => { + await checkStyle(locator, expectedStyles); + }); } - }); - await test.step('Verify weekdays attributes', async () => { - const weekDaysRows = page.locator('[data-ui-name="CalendarWeekDays"]'); - const rowCount = await weekDaysRows.count(); - const daysOfWeek = [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ]; + await test.step('Verify style of selected date', async () => { + await locators.cells(page, 10).click(); + await locators.cells(page, 11).click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - for (let r = 0; r < rowCount; r++) { - const weekDaysRow = weekDaysRows.nth(r); - await expect(weekDaysRow).toHaveAttribute('role', 'row'); - const weekDays = weekDaysRow.locator('[data-ui-name="CalendarWeekDays.Unit"]'); - const unitCount = await weekDays.count(); - expect(unitCount).toBe(daysOfWeek.length); + await locators.dateRangePickerTrigger(page, 4).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - for (let i = 0; i < daysOfWeek.length; i++) { - const day = weekDays.nth(i); - await expect(day).toHaveAttribute('role', 'columnheader'); - await expect(day).toHaveAttribute('aria-label', daysOfWeek[i]); + const cell = page.locator('[data-ui-name="CalendarDays.Unit"][class*="Selected"]'); + await checkStyle(cell.nth(1), { margin: '4px 0px 0px', width: '32px', height: '32px' }); + }); - const text = (await day.textContent())?.trim(); - expect(text).toBe(daysOfWeek[i].slice(0, 3)); - } - } + await test.step('Verify style for Apply picker button', async () => { + await checkStyle(locators.button(page, 'Apply'), { color: 'rgb(255, 255, 255)', backgroundColor: 'rgb(0, 143, 248)' }); + }); }); - await test.step('Verify days attributes', async () => { - const cells = page.locator('[data-ui-name="CalendarDays.Unit"]'); - const cellCount = await cells.count(); - - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; + test('Verify date range picker opened by keyboard', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx', 'en'); + + await page.keyboard.press('Tab'); + await page.keyboard.type('0505202310052023'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + await expect(page).toHaveScreenshot(); + }); + }); - await expect(cell).toHaveAttribute('role', 'gridcell'); - await expect(cell).toHaveAttribute('aria-colindex'); - await expect(cell).toHaveAttribute('aria-rowindex'); + test.describe('Date range picker props', () => { + test('Verify all date range picker props work good', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/day-range-picker.tsx', 'en'); - const date = new Date(ariaLabel); - const isCurrentMonth = date.getMonth() === 5; + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + await expect(page).toHaveScreenshot(); - if (isCurrentMonth) { - expect(hasDisabledAttr).toBe(false); - expect(ariaDisabled).toBe('false'); - } + await locators.cells(page, 3).hover(); + await expect(page).toHaveScreenshot(); - const text = await cell.textContent(); - expect(text?.trim()).not.toBe(''); - } + await locators.button(page, 'Apply').hover(); + await expect(page).toHaveScreenshot(); }); - await test.step('Verify divider attributes', async () => { - const divider = page.locator('[data-ui-name="Divider"]'); - const dividerAttributes = [ - ['orientation', 'vertical'], - ['aria-orientation', 'vertical'], - ['role', 'separator'], - ]; - - for (const [attr, value] of dividerAttributes) { - await expect(divider).toHaveAttribute(attr, value); - } + test('Verify date range picker period work good', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/day-range-picker-perios-props.tsx', 'en'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await expect(page).toHaveScreenshot(); }); + }); - const period = page.locator('[data-ui-name="DateRangePicker.Period"]'); - - await test.step('Verify DateRangePicker.Period attributes', async () => { - const periodAttributes = [ - ['role', 'listbox'], - ['aria-label', 'Presets'], - ]; - - for (const [attr, value] of periodAttributes) { - await expect(period).toHaveAttribute(attr, value); - } + test.describe('Week picker', () => { + test('Verify Week picker trigger when entering date manually', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/week_picker.tsx', 'en'); + + const screenshotsClip = (await locators.dateRangePickerTrigger(page, 0).boundingBox())!; + screenshotsClip.x -= 4; + screenshotsClip.y -= 4; + screenshotsClip.width += 8; + screenshotsClip.height += 8; + + await page.keyboard.press('Tab'); + await page.keyboard.type('05012020'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); }); - const periodButtons = page.locator( - '[data-ui-name="DateRangePicker.Period"] [data-ui-name="Button"]', - ); + test('Verify week picker interacting by mouse', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/week_picker.tsx', 'en'); - await test.step('Verify DateRangePicker.Period button attributes', async () => { - const count = await periodButtons.count(); + await page.keyboard.press('Tab'); + await page.keyboard.type('05012020'); - for (let i = 0; i < count; i++) { - const button = periodButtons.nth(i); - await expect(button).toHaveAttribute('type', 'button'); - await expect(button).toHaveAttribute('role', 'option'); - } - }); + await locators.dateRangePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); - await test.step('Verify Apply and Reset button attributes', async () => { - const buttons = [ - { locator: '[data-ui-name="DateRangePicker.Apply"]', label: 'Apply' }, - { locator: '[data-ui-name="DateRangePicker.Reset"]', label: 'Reset' }, - ]; + await expect(page).toHaveScreenshot(); - for (const { locator, label } of buttons) { - const button = page.locator(locator); - await expect(button).toHaveAttribute('type', 'button'); - } + await locators.cells(page, 15).click(); // Select a day + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + + await expect(locators.popper(page)).not.toBeVisible(); }); }); +}); - test('Verify date range picker styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePickerTrigger = page.locator('[data-ui-name="DateRangePicker.Trigger"]').nth(4); - const prevButton = page.locator('[data-ui-name="DateRangePicker.Prev"]'); - const cells = page.locator('[data-ui-name="CalendarDays.Unit"]'); - const apply = page.locator('[data-ui-name="DateRangePicker.Apply"]'); - - // Helper function to check style properties - const checkStyle = async (element: any, expectedStyles: any) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; +/* ===================================================== +@functional +Keyboard and mouse interactions - no snapshots here. +We verify states, visibility, and attributes. +===================================================== */ +test.describe(`${TAG.FUNCTIONAL}`, () => { + test.describe('Date range with standart ranges', () => { + test('Verify roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx', 'en'); + + await test.step('Verify trigger aria label', async () => { + await expect(locators.dateRangePickerTrigger(page, 4)).toHaveAttribute('aria-label', 'Date field'); + }); - await test.step('Verify trigger margins', async () => { - await checkStyle(datePickerTrigger, { marginTop: '8px' }); - }); + await test.step('Verify trigger svg attributes', async () => { + const svgAttributes = [ + ['tabindex', '-1'], + ['aria-hidden', 'true'], + ['width', '16'], + ['height', '16'], + ]; + const svg = locators.dateRangePickerTrigger(page, 4).locator('svg'); + for (const [attr, value] of svgAttributes) { + await expect(svg).toHaveAttribute(attr, value); + } + }); - await test.step('Verify svg dimensions', async () => { - const svg = datePickerTrigger.locator('svg'); - await checkStyle(svg, { paddingLeft: '8px', paddingRight: '8px' }); - await expect(svg).toHaveAttribute('width', '16'); - await expect(svg).toHaveAttribute('height', '16'); - }); + const inputAttributes = [ + { index: 2, label: 'From date' }, + { index: 3, label: 'To Date field' }, + ]; - await test.step('Verify trigger separator padding', async () => { - const separator = page.locator('[data-ui-name="DateRange.RangeSep"]').nth(1); - await checkStyle(separator, { paddingRight: '8px' }); - }); + for (const { index, label } of inputAttributes) { + await test.step(`Verify ${label} trigger attributes`, async () => { + await expect(locators.dateRangePickerTrigger(page, index)).toHaveAttribute('aria-invalid', 'false'); + await expect(locators.dateRangePickerTrigger(page, index)).toHaveAttribute('aria-haspopup', 'dialog'); + await expect(locators.dateRangePickerTrigger(page, index)).toHaveAttribute('aria-expanded', 'false'); + await expect(locators.dateRangePickerTrigger(page, index)).toHaveAttribute('role', 'combobox'); + await expect(locators.dateRangePickerTrigger(page, index)).toHaveAttribute('aria-label', label); + await expect(locators.dateRangePickerTrigger(page, index)).toHaveAttribute('inputmode', 'numeric'); + }); + } - await test.step('Enter dates and open popper', async () => { - await page.locator('input[data-ui-name="DateRangePicker.Trigger"]').nth(2).fill('05.04.2025'); - await page.locator('input[data-ui-name="DateRangePicker.Trigger"]').nth(3).fill('05.05.2025'); - await datePickerTrigger.click(); - }); + locators.dateRangePickerTrigger(page, 4).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - const dateStyles = [ - { - locator: cells.first(), - expectedStyles: { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }, - }, - { - locator: cells.nth(10), - expectedStyles: { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }, - }, - ]; + await test.step('Verify popper attributes', async () => { + const popperAttributes = [ + ['tabindex', '0'], + ['data-popper-placement', 'bottom-start'], + ]; - for (const { locator, expectedStyles } of dateStyles) { - await test.step(`Verify style of ${locator === cells.first() ? 'disabled' : 'available' - } date`, async () => { - await checkStyle(locator, expectedStyles); + for (const [attr, value] of popperAttributes) { + await expect(locators.popper(page)).toHaveAttribute(attr, value); + } }); - } - - await test.step('Verify style of selected date', async () => { - await cells.nth(10).click(); - await cells.nth(11).click(); - await apply.click(); - await datePickerTrigger.click(); - const cell = page.locator('[data-ui-name="CalendarDays.Unit"][class*="Selected"]'); - await checkStyle(cell.nth(1), { margin: '4px 0px 0px', width: '32px', height: '32px' }); - }); - await test.step('Verify style for Apply picker button', async () => { - await checkStyle(apply, { color: 'rgb(255, 255, 255)', backgroundColor: 'rgb(0, 143, 248)' }); - }); - }); - - function formatAriaLabelToInputValue(ariaLabel: string | null): string { - if (!ariaLabel) { - throw new Error('aria-label is null'); - } - const parsedDate = new Date(ariaLabel); - - if (isNaN(parsedDate.getTime())) { - throw new Error(`Invalid aria-label date: ${ariaLabel}`); - } - - const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); - const day = parsedDate.getDate().toString().padStart(2, '0'); - const year = parsedDate.getFullYear().toString(); - - return `${month}/${day}/${year}`; - } - - test('Verify Date range picker mouse interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/datepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePicker = page.locator('[data-ui-name="DateRangePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DateRangePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DateRangePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DateRangePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DateRangePicker.Next"]'); - const input = page.locator('input[data-ui-name="DateRangePicker.Trigger"]'); - const apply = page.locator('[data-ui-name="DateRangePicker.Apply"]'); - const reset = page.locator('[data-ui-name="DateRangePicker.Reset"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const cells = page.locator('[role="gridcell"]'); - - await test.step('Click on date picker to open popper', async () => { - await datePicker.nth(2).click(); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await datePicker.nth(3).click(); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - }); - - await test.step('Open date picker and check titles', async () => { - await datePicker.first().click(); - await apply.waitFor({ state: 'visible' }); + await test.step('Verify popper header attributes', async () => { + await expect(locators.title(page).first()).toHaveAttribute( + 'aria-live', + 'polite', + ); + await expect(locators.title(page).nth(1)).not.toHaveAttribute('aria-live', ''); + }); - const initialTitle1 = await headTitle.first().textContent(); - const initialTitle2 = await headTitle.nth(1).textContent(); + await test.step('Verify calendar attributes', async () => { + const count = await locators.calendar(page).count(); - await test.step('Click on "Previous month" button', async () => { - await headPrev.click(); - await expect(headTitle.first()).not.toHaveText(initialTitle1!); - await expect(headTitle.nth(1)).not.toHaveText(initialTitle2!); + for (let i = 0; i < count; i++) { + const calendar = locators.calendar(page).nth(i); + await expect(calendar).toHaveAttribute('role', 'grid'); + await expect(calendar).toHaveAttribute('disabled', ''); + } }); - await test.step('Click on "Next month" button', async () => { - await headNext.click(); - await expect(headTitle.first()).toHaveText(initialTitle1!); - await expect(headTitle.nth(1)).toHaveText(initialTitle2!); + await test.step('Verify weekdays attributes', async () => { + const rowCount = await locators.weekDaysRow(page).count(); + const daysOfWeek = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; + + for (let r = 0; r < rowCount; r++) { + const weekDaysRow = locators.weekDaysRow(page).nth(r); + await expect(weekDaysRow).toHaveAttribute('role', 'row'); + const weekDays = weekDaysRow.locator('[data-ui-name="CalendarWeekDays.Unit"]'); + const unitCount = await weekDays.count(); + expect(unitCount).toBe(daysOfWeek.length); + + for (let i = 0; i < daysOfWeek.length; i++) { + const day = weekDays.nth(i); + await expect(day).toHaveAttribute('role', 'columnheader'); + await expect(day).toHaveAttribute('aria-label', daysOfWeek[i]); + + const text = (await day.textContent())?.trim(); + expect(text).toBe(daysOfWeek[i].slice(0, 3)); + } + } }); - }); - let expectedInputValue15 = ''; - await test.step('Select date cells and validate input values', async () => { - await cells.nth(10).click(); - const inputValue = await input.nth(0).inputValue(); - const calendarAriaLabel = await cells.nth(10).getAttribute('aria-label'); - const expectedInputValue = formatAriaLabelToInputValue(calendarAriaLabel); - - await expect(inputValue).toBe(expectedInputValue); - await expect(popper).toBeVisible(); - - await cells.nth(15).click(); - const inputValue15 = await input.nth(1).inputValue(); - const calendarAriaLabel15 = await cells.nth(15).getAttribute('aria-label'); - expectedInputValue15 = formatAriaLabelToInputValue(calendarAriaLabel15); - await expect(inputValue15).toBe(expectedInputValue15); - }); - await test.step('Reset the selected dates', async () => { - await cells.nth(15).click(); - await page.waitForTimeout(300); + await test.step('Verify days attributes', async () => { + const cellCount = await locators.cells(page).count(); - const inputValue1 = await input.nth(0).inputValue(); - const inputValue15_1 = await input.nth(1).inputValue(); + for (let i = 0; i < cellCount; i++) { + const cell = locators.cells(page).nth(i); + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; - await expect(inputValue1).toBe(expectedInputValue15); - await expect(inputValue15_1).toBe(''); + await expect(cell).toHaveAttribute('role', 'gridcell'); + await expect(cell).toHaveAttribute('aria-colindex'); + await expect(cell).toHaveAttribute('aria-rowindex'); - await cells.nth(15).click(); - const inputValue2 = await input.nth(0).inputValue(); - const inputValue15_2 = await input.nth(1).inputValue(); - await expect(inputValue15_2).toBe(expectedInputValue15); - await expect(inputValue2).toBe(expectedInputValue15); - }); - - await test.step('Click on apply and check input values', async () => { - await cells.nth(20).click(); - await cells.nth(25).click(); + const date = new Date(ariaLabel); + const isCurrentMonth = date.getMonth() === 5; - const inputValue20 = await input.nth(0).inputValue(); - const calendarAriaLabel20 = await cells.nth(20).getAttribute('aria-label'); - const expectedInputValue20 = formatAriaLabelToInputValue(calendarAriaLabel20); + const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - const inputValue25 = await input.nth(1).inputValue(); - const calendarAriaLabel25 = await cells.nth(25).getAttribute('aria-label'); - await apply.click(); - await apply.waitFor({ state: 'hidden' }); - await expect(inputValue20).toBe(expectedInputValue20); + if (isCurrentMonth) { + expect(hasDisabledAttr).toBe(false); + expect(ariaDisabled).toBe('false'); + } - const expectedInputValue25 = formatAriaLabelToInputValue(calendarAriaLabel25); - await expect(inputValue25).toBe(expectedInputValue25); - }); + const text = await cell.textContent(); + expect(text?.trim()).not.toBe(''); + } + }); - await test.step('Reset date selection and validate input', async () => { - await datePicker.nth(2).click(); - await reset.click(); - await apply.waitFor({ state: 'hidden' }); + await test.step('Verify divider attributes', async () => { + const dividerAttributes = [ + ['orientation', 'vertical'], + ['aria-orientation', 'vertical'], + ['role', 'separator'], + ]; - const inputValueReset1 = await input.nth(0).inputValue(); - const inputValueReset2 = await input.nth(1).inputValue(); - await expect(inputValueReset1).toBe(''); - await expect(inputValueReset2).toBe(''); - await expect(popper).not.toBeVisible(); - }); + for (const [attr, value] of dividerAttributes) { + await expect(locators.divider(page)).toHaveAttribute(attr, value); + } + }); - await test.step('Click on buttons and check input values', async () => { - await datePicker.nth(2).click(); - await apply.waitFor({ state: 'visible' }); + await test.step('Verify DateRangePicker.Period attributes', async () => { + const periodAttributes = [ + ['role', 'listbox'], + ['aria-label', 'Presets'], + ]; - await buttons.nth(3).click(); - const inputValueDate1 = await input.nth(0).inputValue(); - const inputValueDate2 = await input.nth(1).inputValue(); - await expect(inputValueDate1).not.toBe(''); - await expect(inputValueDate2).not.toBe(''); + for (const [attr, value] of periodAttributes) { + await expect(locators.period(page)).toHaveAttribute(attr, value); + } + }); }); - }); - - test('Verify Date range picker keyboard interactions', async ({ page, browserName }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePicker = page.locator('[data-ui-name="DateRangePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="DateRangePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="DateRangePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="DateRangePicker.Title"]'); - const headNext = page.locator('[data-ui-name="DateRangePicker.Next"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const input = page.locator('input[data-ui-name="DateRangePicker.Trigger"]'); - const apply = page.locator('[data-ui-name="DateRangePicker.Apply"]'); - const reset = page.locator('[data-ui-name="DateRangePicker.Reset"]'); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - - await expect(datePicker.nth(4)).not.toBeFocused(); - await expect(popper).toBeFocused(); - - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await expect(datePicker.nth(4)).not.toBeFocused(); - await expect(popper).toBeFocused(); - - if (browserName === 'webkit') return; - - await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - await headPrev.hover(); - const [initialTitleFrom, initialTitleTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); - - await page.keyboard.press('Enter'); - const [titleAfterFirstEnterFrom, titleAfterFirstEnterTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); - expect(titleAfterFirstEnterFrom).not.toBe(initialTitleFrom); - expect(titleAfterFirstEnterTo).not.toBe(initialTitleTo); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); - - await page.keyboard.press('Enter'); - const [titleAfterSecondEnterFrom, titleAfterSecondEnterTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); - expect(titleAfterSecondEnterFrom).toBe(initialTitleFrom); - expect(titleAfterSecondEnterTo).toBe(initialTitleTo); - - await page.keyboard.press('Shift+Tab'); - await expect(page.locator('[data-ui-name="DateRangePicker.Calendar"]').first()).toBeFocused(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(buttons.first()).toBeFocused(); - - for (let i = 0; i < 5; i++) await page.keyboard.press('Tab'); - await expect(apply).toBeFocused(); - - await page.keyboard.press('Tab'); - await expect(reset).toBeFocused(); - - await page.keyboard.press('Tab'); - await expect(popper).toBeFocused(); - - await page.keyboard.press('ArrowLeft'); - const [initialValue1, initialValue2] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - const [value1_1, value2_1] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - expect(value1_1).toBe(initialValue1); - expect(value2_1).toBe(initialValue2); - - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await page.keyboard.press('ArrowDown'); - await page.keyboard.press('Space'); - const [value1_2, value2_2] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - expect(value1_2).not.toBe(value1_1); - expect(value2_2).toBe(value2_1); - - await page.keyboard.press('Space'); - const [value1_3, value2_3] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - expect(value1_3).toBe(value1_2); - expect(value2_3).not.toBe(value2_2); - - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - const [value1_4, value2_4] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - expect(value1_4).toBe(initialValue1); - expect(value2_4).toBe(initialValue2); - - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await page.keyboard.press('ArrowDown'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Space'); - - for (let i = 0; i < 6; i++) await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - - const [value1_6, value2_6] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - expect(value1_6).not.toBe(value1_4); - expect(value2_6).not.toBe(value2_4); - - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - - for (let i = 0; i < 5; i++) await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - for (let i = 0; i < 10; i++) await page.keyboard.press('Tab'); - await expect(reset).toBeFocused(); - - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - const [value1_5, value2_5] = await Promise.all([ - input.nth(2).inputValue(), - input.nth(3).inputValue(), - ]); - expect(value1_5).toBe(initialValue1); - expect(value2_5).toBe(initialValue2); - }); -}); -test.describe('Date Range picker with custom ranges', () => { - test('Verify Range picker with custom ranges styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + test('Verify Date range picker mouse interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx', 'en'); - await page.setContent(htmlContent); - - await page.keyboard.press('Tab'); - - await page.keyboard.type('0505202310052023'); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await expect(page).toHaveScreenshot(); - }); -}); + const input = page.locator('input[data-ui-name="DateRangePicker.Trigger"]'); -test.describe('Date range picker props', () => { - test('Verify all date range picker props work good', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/day-range-picker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await test.step('Click on date picker to open popper', async () => { + await locators.dateRangePickerTrigger(page, 6).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await page.setContent(htmlContent); + await expect(locators.popper(page)).toHaveCount(1); + await locators.dateRangePickerTrigger(page, 6).click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); + await test.step('Open date picker and check titles', async () => { + await locators.dateRangePickerTrigger(page, 6).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await expect(page).toHaveScreenshot(); + const initialTitle1 = await locators.title(page).first().textContent(); + const initialTitle2 = await locators.title(page).nth(1).textContent(); - const cells = page.locator('[role="gridcell"]'); + await test.step('Click on "Previous month" button', async () => { + await locators.button(page, 'Previous month').click(); + await expect(locators.title(page).first()).not.toHaveText(initialTitle1!); + await expect(locators.title(page).nth(1)).not.toHaveText(initialTitle2!); + }); - await cells.nth(3).hover(); - await expect(page).toHaveScreenshot(); + await test.step('Click on "Next month" button', async () => { + await locators.button(page, 'Next month').click(); + await expect(locators.title(page).first()).toHaveText(initialTitle1!); + await expect(locators.title(page).nth(1)).toHaveText(initialTitle2!); + }); + }); + let expectedInputValue15 = ''; + await test.step('Select date cells and validate input values', async () => { + await locators.cells(page, 10).click(); + const inputValue = await input.nth(2).inputValue(); + const calendarAriaLabel = await locators.cells(page, 10).getAttribute('aria-label'); + const expectedInputValue = formatAriaLabelToInputValue(calendarAriaLabel); + + await expect(inputValue).toBe(expectedInputValue); + + await locators.cells(page, 15).click(); + const inputValue15 = await input.nth(3).inputValue(); + const calendarAriaLabel15 = await locators.cells(page, 15).getAttribute('aria-label'); + expectedInputValue15 = formatAriaLabelToInputValue(calendarAriaLabel15); + await expect(inputValue15).toBe(expectedInputValue15); + }); - const apply = page.locator('[data-ui-name="DateRangePicker.Apply"]'); + await test.step('Reset the selected dates', async () => { + await locators.cells(page, 15).click(); + await page.waitForTimeout(300); - await apply.hover(); - await expect(page).toHaveScreenshot(); - }); + const inputValue1 = await input.nth(2).inputValue(); + const inputValue15_1 = await input.nth(3).inputValue(); - test('Verify date range picker period work good', async ({ page }) => { - const standPath = - 'stories/components/date-picker/tests/examples/day-range-picker-perios-props.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await expect(inputValue1).toBe(expectedInputValue15); + await expect(inputValue15_1).toBe(''); - await page.setContent(htmlContent); + await locators.cells(page, 15).click(); + const inputValue2 = await input.nth(2).inputValue(); + const inputValue15_2 = await input.nth(3).inputValue(); + await expect(inputValue15_2).toBe(expectedInputValue15); + await expect(inputValue2).toBe(expectedInputValue15); + }); - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); + await test.step('Click on apply and check input values', async () => { + await locators.cells(page, 20).click(); + await locators.cells(page, 25).click(); - await expect(page).toHaveScreenshot(); - }); -}); + const inputValue20 = await input.nth(2).inputValue(); + const calendarAriaLabel20 = await locators.cells(page, 20).getAttribute('aria-label'); + const expectedInputValue20 = formatAriaLabelToInputValue(calendarAriaLabel20); -test.describe('Week picker', () => { - test('Verify Week picker trigger when entering date manually', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/week_picker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + const inputValue25 = await input.nth(3).inputValue(); + const calendarAriaLabel25 = await locators.cells(page, 25).getAttribute('aria-label'); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - await page.setContent(htmlContent); + await expect(inputValue20).toBe(expectedInputValue20); - const datePicker = await page.locator('[data-ui-name="DateRangePicker.Trigger"]'); - const screenshotsClip = (await datePicker.first().boundingBox())!; - screenshotsClip.x -= 4; - screenshotsClip.y -= 4; - screenshotsClip.width += 8; - screenshotsClip.height += 8; + const expectedInputValue25 = formatAriaLabelToInputValue(calendarAriaLabel25); + await expect(inputValue25).toBe(expectedInputValue25); + }); - await page.keyboard.press('Tab'); - await page.keyboard.type('05012020'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await test.step('Reset date selection and validate input', async () => { + await locators.dateRangePickerTrigger(page, 6).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - }); + await locators.button(page, 'Reset').click(); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); - const setupDatePicker = async (page: any) => { - const standPath = 'stories/components/date-picker/docs/examples/week_picker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); + const inputValueReset1 = await input.nth(2).inputValue(); + const inputValueReset2 = await input.nth(3).inputValue(); + await expect(inputValueReset1).toBe(''); + await expect(inputValueReset2).toBe(''); + }); - const datePicker = await page.locator('[data-ui-name="DateRangePicker.Trigger"]'); - const popper = await page.locator('[data-ui-name="DateRangePicker.Popper"]'); + await test.step('Click on buttons and check input values', async () => { + await locators.dateRangePickerTrigger(page, 6).click(); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await page.keyboard.press('Tab'); - await page.keyboard.type('05012020'); + await locators.option(page, 'Last month').click(); + const inputValueDate1 = await input.nth(2).inputValue(); + const inputValueDate2 = await input.nth(3).inputValue(); + await expect(inputValueDate1).not.toBe(''); + await expect(inputValueDate2).not.toBe(''); + }); + }); - await datePicker.first().click(); - return { datePicker, popper }; - }; + test('Verify Date range picker keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker', + '@base-components'], + }, async ({ page, browserName }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/custom_date_ranges.tsx', 'en'); + + const buttons = page.locator('[data-ui-name="Button"]'); + const input = page.locator('input[data-ui-name="DateRangePicker.Trigger"]'); + await test.step('Open date range picker by Enter', async () => { + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await expect(locators.dateRangePickerTrigger(page, 4)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); - test('Verify week picker interacting by mouse', async ({ page }) => { - const { datePicker, popper } = await setupDatePicker(page); + await test.step('Close date range picker by Escape', async () => { + await page.keyboard.press('Escape'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + }); + await test.step('Open date range picker by Space', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); - await expect(page).toHaveScreenshot(); + await expect(locators.dateRangePickerTrigger(page, 4)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); + // if (browserName === 'webkit') return; + await test.step('Verify month switched by Enter', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + const [initialTitleFrom, initialTitleTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); + + await page.keyboard.press('Enter'); + const [titleAfterFirstEnterFrom, titleAfterFirstEnterTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); + expect(titleAfterFirstEnterFrom).not.toBe(initialTitleFrom); + expect(titleAfterFirstEnterTo).not.toBe(initialTitleTo); + + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + + await page.keyboard.press('Space'); + const [titleAfterSecondEnterFrom, titleAfterSecondEnterTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); + expect(titleAfterSecondEnterFrom).toBe(initialTitleFrom); + expect(titleAfterSecondEnterTo).toBe(initialTitleTo); + }); - const cells = page.locator('[data-ui-name="CalendarDays.Unit"]'); - await cells.nth(15).click(); // Select a day - await expect(popper).not.toBeVisible(); + await test.step('Verify navigation inside popper and date range selection', async () => { + await page.keyboard.press('Shift+Tab'); + await expect(page.locator('[data-ui-name="DateRangePicker.Calendar"]').first()).toBeFocused(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(buttons.first()).toBeFocused(); + + for (let i = 0; i < 5; i++) await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Apply')).toBeFocused(); + + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Reset')).toBeFocused(); + + await page.keyboard.press('Tab'); + await expect(locators.popper(page)).toBeFocused(); + + await page.keyboard.press('ArrowLeft'); + const [initialValue1, initialValue2] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + + await page.keyboard.press('Escape'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + await expect(locators.popper(page)).toHaveCount(0); + const [value1_1, value2_1] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + expect(value1_1).toBe(initialValue1); + expect(value2_1).toBe(initialValue2); + + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Space'); + const [value1_2, value2_2] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + expect(value1_2).not.toBe(value1_1); + expect(value2_2).toBe(value2_1); + + await page.keyboard.press('Space'); + const [value1_3, value2_3] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + expect(value1_3).toBe(value1_2); + expect(value2_3).not.toBe(value2_2); + + await page.keyboard.press('Escape'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + const [value1_4, value2_4] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + expect(value1_4).toBe(initialValue1); + expect(value2_4).toBe(initialValue2); + + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Space'); + + for (let i = 0; i < 6; i++) await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + const [value1_6, value2_6] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + expect(value1_6).not.toBe(value1_4); + expect(value2_6).not.toBe(value2_4); + + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + for (let i = 0; i < 5; i++) await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + await page.keyboard.press('Enter'); + await locators.button(page, 'Apply').waitFor({ state: 'visible' }); + + for (let i = 0; i < 10; i++) await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Reset')).toBeFocused(); + + await page.keyboard.press('Space'); + await locators.button(page, 'Apply').waitFor({ state: 'hidden' }); + + const [value1_5, value2_5] = await Promise.all([ + input.nth(2).inputValue(), + input.nth(3).inputValue(), + ]); + expect(value1_5).toBe(initialValue1); + expect(value2_5).toBe(initialValue2); + }); + }); }); - test('Verify week picker interacting by keyboard', async ({ page }) => { - const { datePicker, popper } = await setupDatePicker(page); - - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await expect(page).toHaveScreenshot(); - - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowDown'); - await expect(page).toHaveScreenshot(); + test.describe('Week picker', () => { + test('Verify week picker interacting by keyboard', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker', + '@base-components'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/week_picker.tsx', 'en'); + await page.keyboard.press('Tab'); + await page.keyboard.type('05012020'); + + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous month')).toBeFocused(); + await page.keyboard.press('Enter'); + await page.keyboard.press('Space'); + await page.keyboard.press('Space'); + await expect(locators.button(page, 'Previous month')).toBeVisible(); + + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowUp'); + await page.keyboard.press('ArrowUp'); + + await page.keyboard.press('Space'); // enter doesn't work + await locators.button(page, 'Previous month').waitFor({ state: 'hidden' }); + + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous month').waitFor({ state: 'visible' }); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next month')).toBeFocused(); + await expect(locators.button(page, 'Previous month')).toBeVisible(); + }); }); }); diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png new file mode 100644 index 0000000000..c99a5c13ec Binary files /dev/null and b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-Range-Trigger-Verify-trigger-states-when-entering-sate-manually-4-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-all-date-range-picker-props-work-good-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-date-range-picker-period-work-good-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-date-range-picker-period-work-good-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-date-range-picker-period-work-good-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-date-range-picker-period-work-good-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-date-range-picker-period-work-good-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-date-range-picker-period-work-good-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-date-range-picker-period-work-good-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-date-range-picker-period-work-good-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-date-range-picker-period-work-good-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-date-range-picker-period-work-good-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-range-picker-props-Verify-date-range-picker-period-work-good-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-picker-props-Verify-date-range-picker-period-work-good-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-picker-with-custom-ranges-Verify-Range-picker-with-custom-ranges-styles-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-with-standart-ranges-Verify-date-range-picker-opened-by-keyboard-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-picker-with-custom-ranges-Verify-Range-picker-with-custom-ranges-styles-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-with-standart-ranges-Verify-date-range-picker-opened-by-keyboard-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-picker-with-custom-ranges-Verify-Range-picker-with-custom-ranges-styles-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-with-standart-ranges-Verify-date-range-picker-opened-by-keyboard-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-picker-with-custom-ranges-Verify-Range-picker-with-custom-ranges-styles-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-with-standart-ranges-Verify-date-range-picker-opened-by-keyboard-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-picker-with-custom-ranges-Verify-Range-picker-with-custom-ranges-styles-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-with-standart-ranges-Verify-date-range-picker-opened-by-keyboard-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-picker-with-custom-ranges-Verify-Range-picker-with-custom-ranges-styles-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Date-range-with-standart-ranges-Verify-date-range-picker-opened-by-keyboard-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-Week-picker-trigger-when-entering-date-manually-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-week-picker-interacting-by-mouse-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-1-chromium-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-week-picker-interacting-by-mouse-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-week-picker-interacting-by-mouse-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-1-firefox-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-week-picker-interacting-by-mouse-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-week-picker-interacting-by-mouse-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-1-webkit-linux.png rename to semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/-visual-Week-picker-Verify-week-picker-interacting-by-mouse-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png deleted file mode 100644 index dc492a0156..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Date-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-chromium-linux.png deleted file mode 100644 index 6e40eff229..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-firefox-linux.png deleted file mode 100644 index 5a83ac5b62..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-firefox-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-webkit-linux.png deleted file mode 100644 index 14bc413674..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-keyboard-2-webkit-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-chromium-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-chromium-linux.png deleted file mode 100644 index 017ce6f651..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-firefox-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-firefox-linux.png deleted file mode 100644 index a67b896380..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-firefox-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-webkit-linux.png b/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-webkit-linux.png deleted file mode 100644 index 6bfc5340e3..0000000000 Binary files a/semcore/date-picker/__tests__/date-range-picker.browser-test.tsx-snapshots/Week-picker-Verify-week-picker-interacting-by-mouse-1-webkit-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/index.test.tsx b/semcore/date-picker/__tests__/index.test.tsx index 9ed6caada2..423b10e54e 100644 --- a/semcore/date-picker/__tests__/index.test.tsx +++ b/semcore/date-picker/__tests__/index.test.tsx @@ -1,5 +1,4 @@ import { runDependencyCheckTests } from '@semcore/testing-utils/shared-tests'; -import { snapshot } from '@semcore/testing-utils/snapshot'; import { cleanup, render, fireEvent, act, userEvent } from '@semcore/testing-utils/testing-library'; import { expect, test, describe, beforeEach, vi } from '@semcore/testing-utils/vitest'; import React from 'react'; @@ -8,9 +7,6 @@ import { mockDate, RealDate } from './utils'; import { DatePicker, DateRangePicker, - MonthRangePicker, - DateRangeComparator, - MonthDateRangeComparator, } from '../src'; describe('date-picker Dependency imports', () => { @@ -78,36 +74,6 @@ describe('DateRangePicker', () => { expect(spy).toBeCalledWith([DateRangePicker.subtract(today, 1, 'day'), today]); }); - test('Verify picker renders correctly if one day is selected', async ({ task }) => { - const component = ( - - ); - await expect(await snapshot(component)).toMatchImageSnapshot(task); - }); - - test('Verify picker renders correctly if the same month of a different year is selected', async ({ - task, - }) => { - const component = ( - - ); - await expect(await snapshot(component)).toMatchImageSnapshot(task); - }); - - test('Verify localized placeholder renders correctly', async ({ task }) => { - const component = ( - - - - - ); - await expect(await snapshot(component)).toMatchImageSnapshot(task); - }); - test('Verify trigger suppports set custom displayPeriod', () => { mockDate('2020-02-10T12:00:00.808Z'); const { getByText, rerender } = render( @@ -189,65 +155,4 @@ describe('DateRangePicker', () => { expect(getByText('February 2024')).toBeTruthy(); }); - - test('Verify renders correctly with empty period', async ({ task, expect }) => { - mockDate('2024-01-20T12:00:00.000Z'); - - const component = ( - - ); - - await expect(await snapshot(component)).toMatchImageSnapshot(task); - }); -}); - -describe('DateRangeComparator', () => { - beforeEach(() => { - global.Date = RealDate; - cleanup(); - }); - const disablePopper = { __disablePopper: true } as any; - - test('Verify renders correctly', async ({ task }) => { - const value = { - value: [new Date('January 5, 2021 00:00:00'), new Date('January 10, 2021 00:00:00')], - compare: [new Date('January 8, 2021 00:00:00'), new Date('January 12, 2021 00:00:00')], - }; - const displayPeriod = new Date('January 5, 2021 00:00:00'); - const component = ( - - ); - await expect(await snapshot(component)).toMatchImageSnapshot(task); - }); - - test('Verify renders correctly monthes', async ({ task }) => { - const value = { - value: [new Date('January 5, 2021 00:00:00'), new Date('May 10, 2021 00:00:00')], - compare: [new Date('Februrary 8, 2021 00:00:00'), new Date('September 12, 2021 00:00:00')], - }; - const displayPeriod = new Date('January 5, 2021 00:00:00'); - const component = ( - - ); - await expect(await snapshot(component)).toMatchImageSnapshot(task); - }); }); diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx b/semcore/date-picker/__tests__/month-picker.browser-test.tsx index 017cd07c9c..9ae5ecaf8e 100644 --- a/semcore/date-picker/__tests__/month-picker.browser-test.tsx +++ b/semcore/date-picker/__tests__/month-picker.browser-test.tsx @@ -1,395 +1,384 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, test } from '@semcore/testing-utils/playwright'; +import type { Page } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; + +export const locators = { + + button: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('button', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + + monthPickerTrigger: (page: Page, index?: number) => { + const base = page.locator('[data-ui-name="MonthPicker.Trigger"]'); + return typeof index === 'number' ? base.nth(index) : base; + }, + calendar: (page: Page) => page.locator('[data-ui-name="MonthPicker.Calendar"]'), + weekDaysRow: (page: Page) => page.locator('[data-ui-name="CalendarWeekDays"]'), + divider: (page: Page) => page.locator('[data-ui-name="Divider"]'), + cells: (page: Page, index?: number) => { + const base = page.getByRole('gridcell'); + return typeof index === 'number' ? base.nth(index) : base; + }, + dateRangeHeader: (page: Page) => page.locator('[data-ui-name="MonthPicker.Header"]'), + + popper: (page: Page) => page.getByRole('dialog'), + title: (page: Page) => page.locator('[data-ui-name="MonthPicker.Title"]'), + period: (page: Page) => page.locator('[data-ui-name="MonthPicker.Period"]'), +}; + +/* ===================================================== +@visual +Visual states, hover and focus styles, paddings, margins, and snapshots. +===================================================== */ +test.describe(`${TAG.VISUAL}`, () => { + test.describe('Month Picker Trigger', () => { + test('Verify trigger entering date manually', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + + const screenshotsClip = (await locators.monthPickerTrigger(page, 0).boundingBox())!; + screenshotsClip.x -= 4; + screenshotsClip.y -= 4; + screenshotsClip.width += 8; + screenshotsClip.height += 8; -test.describe('Month Picker Trigger', () => { - test('Verify trigger entering date manually', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePicker = await page.locator('[data-ui-name="MonthPicker.Trigger"]'); - const screenshotsClip = (await datePicker.first().boundingBox())!; - screenshotsClip.x -= 4; - screenshotsClip.y -= 4; - screenshotsClip.width += 8; - screenshotsClip.height += 8; - - await page.keyboard.press('Tab'); - await page.keyboard.type('052000'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - }); + await page.keyboard.press('Tab'); + await page.keyboard.type('052000'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - test('Verify trigger states and props', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/month-trigger.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Backspace'); + await page.keyboard.press('Backspace'); + await page.keyboard.press('Backspace'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + }); - await page.setContent(htmlContent); + test('Verify trigger states and props', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/month-trigger.tsx', 'en'); - await expect(page).toHaveScreenshot(); + await expect(page).toHaveScreenshot(); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); + for (let i = 0; i < 5; i++) await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); + }); }); -}); -test.describe('Month picker', () => { - test('Verify roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + test.describe('Month picker', () => { + test('Verify month with styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + + const selectedCell = page.locator('[data-ui-name="CalendarMonths.Unit"][class*="Selected"]'); + + const checkStyle = async (element: any, expectedStyles: Record) => { + for (const [property, expectedValue] of Object.entries(expectedStyles)) { + const actualValue = await element.evaluate( + (el: any, property: any) => getComputedStyle(el)[property], + property, + ); + expect(actualValue).toBe(expectedValue); + } + }; - await page.setContent(htmlContent); + await test.step('Verify trigger margins', async () => { + await checkStyle(locators.monthPickerTrigger(page, 0), { + marginTop: '8px', + }); + }); - const datePickerTrigger = page.locator('[data-ui-name="MonthPicker.Trigger"]'); + await locators.monthPickerTrigger(page, 0).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Verify trigger aria label', async () => { - await expect(datePickerTrigger.first()).toHaveAttribute('aria-label', 'Date field'); - }); + await test.step('Verify style of month cell', async () => { + await checkStyle(locators.cells(page, 2), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - await test.step('Verify trigger svg attributes', async () => { - const svg = datePickerTrigger.locator('svg'); - const svgAttributes = [ - ['tabindex', '-1'], - ['aria-hidden', 'true'], - ['width', '16'], - ['height', '16'], - ]; - - for (const [attr, value] of svgAttributes) { - await expect(svg).toHaveAttribute(attr, value); - } + await test.step('Verify style of selected date', async () => { + await checkStyle(selectedCell, { + color: 'rgb(255, 255, 255)', + backgroundColor: 'rgb(43, 179, 255)', + margin: '4px 0px 0px', + width: '60px', + height: '32px', + }); + }); }); + }); +}); - const inputTrigger = page.locator('input[data-ui-name="MonthPicker.Trigger"]'); - - await test.step('Verify input trigger attributes', async () => { - const inputAttributes = [ - ['aria-invalid', 'false'], - ['role', 'combobox'], - ['aria-label', 'Date'], - ['inputmode', 'numeric'], - ]; +/* ===================================================== +@functional +Keyboard and mouse interactions - no snapshots here. +We verify states, visibility, and attributes. +===================================================== */ +test.describe(`${TAG.FUNCTIONAL}`, () => { + test.describe('Month picker', () => { + test('Verify roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + + await test.step('Verify trigger aria label', async () => { + await expect(locators.monthPickerTrigger(page, 0)).toHaveAttribute('aria-label', 'Date field'); + }); - for (const [attr, value] of inputAttributes) { - await expect(inputTrigger).toHaveAttribute(attr, value); - } - }); + await test.step('Verify trigger svg attributes', async () => { + const svg = locators.monthPickerTrigger(page).locator('svg'); + const svgAttributes = [ + ['tabindex', '-1'], + ['aria-hidden', 'true'], + ['width', '16'], + ['height', '16'], + ]; - await datePickerTrigger.first().click(); - const popper = page.locator('[data-ui-name="MonthPicker.Popper"]'); + for (const [attr, value] of svgAttributes) { + await expect(svg).toHaveAttribute(attr, value); + } + }); - await test.step('Verify popper attributes', async () => { - const popperAttributes = [ - ['tabindex', '0'], - ['role', 'dialog'], - ['data-popper-placement', 'bottom-start'], - ]; + const inputTrigger = page.locator('input[data-ui-name="MonthPicker.Trigger"]'); - for (const [attr, value] of popperAttributes) { - await expect(popper).toHaveAttribute(attr, value); - } - }); + await test.step('Verify input trigger attributes', async () => { + const inputAttributes = [ + ['aria-invalid', 'false'], + ['role', 'combobox'], + ['aria-label', 'Date'], + ['inputmode', 'numeric'], + ]; - await test.step('Verify popper header attributes', async () => { - const headerAttributes = [ - { - locator: '[data-ui-name="MonthPicker.Prev"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Previous year'], - ], - }, - { locator: '[data-ui-name="MonthPicker.Title"]', attrs: [['aria-live', 'polite']] }, - { - locator: '[data-ui-name="MonthPicker.Next"]', - attrs: [ - ['type', 'button'], - ['aria-label', 'Next year'], - ], - }, - ]; - - for (const { locator, attrs } of headerAttributes) { - const element = page.locator(locator); - for (const [attr, value] of attrs) { - await expect(element).toHaveAttribute(attr, value); + for (const [attr, value] of inputAttributes) { + await expect(inputTrigger).toHaveAttribute(attr, value); } - } - }); + }); - await test.step('Verify calendar attributes', async () => { - const calendar = page.locator('[data-ui-name="MonthPicker.Calendar"]'); - const calendarAttributes = [ - ['tabindex', '0'], - ['role', 'grid'], - ['disabled', ''], - ]; - - for (const [attr, value] of calendarAttributes) { - await expect(calendar).toHaveAttribute(attr, value); - } - }); + await locators.monthPickerTrigger(page, 0).click(); - await test.step('Verify days attributes', async () => { - const cells = page.locator('[role="gridcell"]'); - const cellCount = await cells.count(); + await test.step('Verify popper attributes', async () => { + const popperAttributes = [ + ['tabindex', '0'], + ['data-popper-placement', 'bottom-start'], + ]; - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; + for (const [attr, value] of popperAttributes) { + await expect(locators.popper(page)).toHaveAttribute(attr, value); + } + }); - const commonAttributes = [ - ['role', 'gridcell'], - ['aria-selected', 'false'], - ['aria-hidden', 'false'], + await test.step('Verify calendar attributes', async () => { + const calendarAttributes = [ + ['tabindex', '0'], + ['role', 'grid'], + ['disabled', ''], ]; - for (const [attr, value] of commonAttributes) { - await expect(cell).toHaveAttribute(attr, value); + for (const [attr, value] of calendarAttributes) { + await expect(locators.calendar(page)).toHaveAttribute(attr, value); } + }); - await expect(cell).toHaveAttribute('aria-colindex'); - await expect(cell).toHaveAttribute('aria-rowindex'); + await test.step('Verify days attributes', async () => { + const cellCount = await locators.cells(page).count(); - const date = new Date(ariaLabel); - const month = date.getMonth(); - const isCurrentMonth = month === 5; + for (let i = 0; i < cellCount; i++) { + const cell = locators.cells(page).nth(i); + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; - const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + const commonAttributes = [ + ['aria-selected', 'false'], + ['aria-hidden', 'false'], + ]; - if (isCurrentMonth) { - expect(hasDisabledAttr).toBe(false); - expect(ariaDisabled).toBe('false'); - } - - // Text content check - const text = await cell.textContent(); - expect(text?.trim()).not.toBe(''); - } - }); - }); + for (const [attr, value] of commonAttributes) { + await expect(cell).toHaveAttribute(attr, value); + } - test('Verify month with styles', async ({ page, browserName }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await expect(cell).toHaveAttribute('aria-colindex'); + await expect(cell).toHaveAttribute('aria-rowindex'); - await page.setContent(htmlContent); + const date = new Date(ariaLabel); + const month = date.getMonth(); + const isCurrentMonth = month === 5; - const datePickerTrigger = page.locator('[data-ui-name="MonthPicker.Trigger"]'); - const prevButton = page.locator('[data-ui-name="MonthPicker.Prev"]'); - const cells = page.locator('[role="gridcell"]'); - const selectedCell = page.locator('[data-ui-name="CalendarMonths.Unit"][class*="Selected"]'); + const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - const checkStyle = async (element: any, expectedStyles: Record) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; + if (isCurrentMonth) { + expect(hasDisabledAttr).toBe(false); + expect(ariaDisabled).toBe('false'); + } - await test.step('Verify trigger margins', async () => { - await checkStyle(datePickerTrigger.first(), { - marginTop: '8px', + // Text content check + const text = await cell.textContent(); + expect(text?.trim()).not.toBe(''); + } }); }); - await datePickerTrigger.first().click(); + test('Verify month picker by mouse interaction', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); - await test.step('Verify style of month cell', async () => { - await checkStyle(cells.nth(2), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }); - }); + const input = page.locator('input[data-ui-name="MonthPicker.Trigger"]'); + const initialValue = await input.inputValue(); - await test.step('Verify style of selected date', async () => { - await checkStyle(selectedCell, { - color: 'rgb(255, 255, 255)', - backgroundColor: 'rgb(43, 179, 255)', - margin: '4px 0px 0px', - width: '60px', - height: '32px', - }); - }); - }); + input.fill('012024'); - test('Verify month picker by mouse interaction', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePicker = page.locator('[data-ui-name="MonthPicker.Trigger"]'); - const popper = page.locator('[data-ui-name="MonthPicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="MonthPicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthPicker.Title"]'); - const headNext = page.locator('[data-ui-name="MonthPicker.Next"]'); - const input = page.locator('input[data-ui-name="MonthPicker.Trigger"]'); - const initialValue = await input.inputValue(); - - input.fill('012024'); - - await test.step('Open and close popper with click', async () => { - await datePicker.first().click(); - await page.waitForTimeout(300); - await expect(popper).toBeVisible(); - await datePicker.first().click(); - await expect(popper).not.toBeVisible(); - await datePicker.first().click(); - await page.waitForTimeout(300); - }); + await test.step('Open and close popper with click', async () => { + await locators.monthPickerTrigger(page, 0).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - const initialTitle = await headTitle.textContent(); + await locators.monthPickerTrigger(page, 0).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); - await test.step('Navigate months with header buttons', async () => { - await headPrev.click(); - await expect(headTitle).not.toHaveText(initialTitle!); + await locators.monthPickerTrigger(page, 0).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + }); - await headNext.click(); - await expect(headTitle).toHaveText(initialTitle!); - }); + const initialTitle = await locators.title(page).textContent(); - const cells = page.locator('[role="gridcell"]'); + await test.step('Navigate months with header buttons', async () => { + await locators.button(page, 'Previous year').click(); + await expect(locators.title(page)).not.toHaveText(initialTitle!); - await test.step('Select month and check popper visibility', async () => { - await cells.nth(3).click(); - await expect(popper).not.toBeVisible(); - }); - const label = page.locator('label[for="simple-month-picker"]'); + await locators.button(page, 'Next year').click(); + await expect(locators.title(page)).toHaveText(initialTitle!); + }); - await test.step('Open calendar from label and select another month', async () => { - await label.click(); - await expect(popper).toBeVisible(); + await test.step('Select month and check popper visibility', async () => { + await locators.cells(page, 3).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + }); + const label = page.locator('label[for="simple-month-picker"]'); - await cells.nth(4).click(); + await test.step('Open calendar from label and select another month', async () => { + await label.click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - const newValue = await input.inputValue(); - await expect(newValue).not.toBe(initialValue); - }); + await locators.cells(page, 4).click(); - await test.step('Enter date manually and open popper', async () => { - await page.locator('input[data-ui-name="MonthPicker.Trigger"]').fill('05.2024'); - await label.click(); - await expect(popper).toBeVisible(); - await page.waitForTimeout(300); - await expect(page).toHaveScreenshot(); + const newValue = await input.inputValue(); + await expect(newValue).not.toBe(initialValue); + }); }); - }); - test('Month picker keyboard interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + test('Month picker keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); - await page.setContent(htmlContent); + const input = page.locator('input[data-ui-name="MonthPicker.Trigger"]'); + const initialValue = await input.inputValue(); - const datePicker = page.locator('[data-ui-name="MonthPicker.Trigger"]'); - const popper = page.locator('[data-ui-name="MonthPicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="MonthPicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthPicker.Title"]'); - const headNext = page.locator('[data-ui-name="MonthPicker.Next"]'); - const input = page.locator('input[data-ui-name="MonthPicker.Trigger"]'); - const initialValue = await input.inputValue(); + await test.step('Open popper with Enter', async () => { + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Open popper with Enter', async () => { - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); - await expect(popper).toBeVisible(); - await expect(datePicker.first()).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); + await expect(locators.monthPickerTrigger(page, 0)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + }); - await test.step('Close popper with Escape', async () => { - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); - await expect(input).toBeFocused(); - }); + await test.step('Close popper with Escape', async () => { + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); - await test.step('Open popper with Space', async () => { - await page.keyboard.press('Space'); - await expect(popper).toBeVisible(); - await expect(datePicker.first()).not.toBeFocused(); - await expect(popper).toBeFocused(); - }); - const initialTitle = await headTitle.textContent(); + await expect(input).toBeFocused(); + }); - await test.step('Navigate to Previous month and validate change', async () => { - await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - await headPrev.hover(); - await page.keyboard.press('Enter'); - const titleAfterFirstEnter = await headTitle.textContent(); - expect(titleAfterFirstEnter).not.toBe(initialTitle); - await expect(headTitle).not.toHaveText(initialTitle!); - }); + await test.step('Open popper with Space', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await expect(locators.monthPickerTrigger(page, 0)).not.toBeFocused(); + }); + const initialTitle = await locators.title(page).textContent(); + + await test.step('Navigate to Previous month and validate change', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous year')).toBeFocused(); + await locators.button(page, 'Previous year').hover(); + await page.keyboard.press('Enter'); + const titleAfterFirstEnter = await locators.title(page).textContent(); + expect(titleAfterFirstEnter).not.toBe(initialTitle); + await expect(locators.title(page)).not.toHaveText(initialTitle!); + }); - await test.step('Navigate to Next month and validate restore', async () => { - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); + await test.step('Navigate to Next month and validate restore', async () => { + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next year')).toBeFocused(); - await page.keyboard.press('Enter'); - const titleAfterSecondEnter = await headTitle.textContent(); - expect(titleAfterSecondEnter).toBe(initialTitle); - }); + await page.keyboard.press('Enter'); + const titleAfterSecondEnter = await locators.title(page).textContent(); + expect(titleAfterSecondEnter).toBe(initialTitle); + }); - await test.step('Navigate to calendar grid', async () => { - await page.keyboard.press('Shift+Tab'); - await expect(headPrev).toBeFocused(); + await test.step('Navigate to calendar grid', async () => { + await page.keyboard.press('Shift+Tab'); + await expect(locators.button(page, 'Previous year')).toBeFocused(); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page.locator('[data-ui-name="MonthPicker.Calendar"]')).toBeFocused(); - }); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page.locator('[data-ui-name="MonthPicker.Calendar"]')).toBeFocused(); + }); - await test.step('Navigate months and select via keyboard', async () => { - await page.keyboard.press('ArrowLeft'); + await test.step('Navigate months and select via keyboard', async () => { + await page.keyboard.press('ArrowLeft'); - const highlighted = page.locator( - '[data-ui-name="CalendarMonths.Unit"][class*="highlighted"]', - ); - await expect(highlighted).toBeVisible(); + const highlighted = page.locator( + '[data-ui-name="CalendarMonths.Unit"][class*="highlighted"]', + ); + await expect(highlighted).toBeVisible(); - const activeElementHandle = await page.evaluateHandle(() => document.activeElement); - const isFocusedElementHighlighted = await highlighted.evaluate( - (el, active) => el === active, - activeElementHandle, - ); - expect(isFocusedElementHighlighted).toBe(true); + const activeElementHandle = await page.evaluateHandle(() => document.activeElement); + const isFocusedElementHighlighted = await highlighted.evaluate( + (el, active) => el === active, + activeElementHandle, + ); + expect(isFocusedElementHighlighted).toBe(true); - await page.keyboard.press('Enter'); - await expect(popper).not.toBeVisible(); - }); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + }); - await test.step('Select another month with Space key', async () => { - await page.keyboard.press('Enter'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('Space'); + await test.step('Select another month with Space key', async () => { + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('Space'); - await expect(popper).not.toBeVisible(); - const newValue = await input.inputValue(); - expect(newValue).not.toBe(initialValue); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + const newValue = await input.inputValue(); + expect(newValue).not.toBe(initialValue); + }); }); }); }); diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-chromium-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-firefox-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-webkit-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-chromium-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-firefox-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-webkit-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-chromium-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-firefox-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-webkit-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-entering-date-manually-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png rename to semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/-visual-Month-Picker-Trigger-Verify-trigger-states-and-props-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-chromium-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-chromium-linux.png deleted file mode 100644 index 275c9dbc56..0000000000 Binary files a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-firefox-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-firefox-linux.png deleted file mode 100644 index 601324446e..0000000000 Binary files a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-firefox-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-webkit-linux.png b/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-webkit-linux.png deleted file mode 100644 index ab6adcc473..0000000000 Binary files a/semcore/date-picker/__tests__/month-picker.browser-test.tsx-snapshots/Month-picker-Verify-month-picker-by-mouse-interaction-1-webkit-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx index c7271715e1..98246ec29b 100644 --- a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx +++ b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx @@ -1,672 +1,609 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, test } from '@semcore/testing-utils/playwright'; +import type { Page } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; -test.describe('MonthRangeComparator range', () => { - test('Verify roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); +import { checkStyle } from './utils'; - await page.setContent(htmlContent); +export function formatAriaLabelToInputValue(ariaLabel: string | null): string { + if (!ariaLabel) { + throw new Error('aria-label is null'); + } - const datePickerTrigger = page.locator( - 'button[data-ui-name="MonthDateRangeComparator.Trigger"]', - ); + let parsedDate = new Date(ariaLabel); - await test.step('Verify trigger attributes', async () => { - await expect(datePickerTrigger).toHaveAttribute('tabindex', '0'); - await expect(datePickerTrigger).toHaveAttribute('aria-haspopup', 'dialog'); - await expect(datePickerTrigger).toHaveAttribute('role', 'button'); - await expect(datePickerTrigger).toHaveAttribute('type', 'button'); - }); + if (isNaN(parsedDate.getTime())) { + parsedDate = new Date(`${ariaLabel} 1`); + } - await test.step('Verify trigger svg attributes', async () => { - const svg = datePickerTrigger.locator('svg'); - await expect(svg).toHaveAttribute('tabindex', '-1'); - await expect(svg).toHaveAttribute('aria-hidden', 'true'); - await expect(svg).toHaveAttribute('width', '16'); - await expect(svg).toHaveAttribute('height', '16'); - }); + if (isNaN(parsedDate.getTime())) { + throw new Error(`Invalid aria-label date: ${ariaLabel}`); + } - // Trigger click to open the popper - datePickerTrigger.click(); - const popper = page.locator('[data-ui-name="MonthDateRangeComparator.Popper"]'); + const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); + const day = parsedDate.getDate().toString().padStart(2, '0'); + const year = parsedDate.getFullYear().toString(); + + return `${month}/${year}`; +} + +export const locators = { + + button: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('button', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + + monthRangeComparatorPickerTrigger: (page: Page, index?: number) => { + const base = page.locator('[data-ui-name="MonthDateRangeComparator.Trigger"]'); + return typeof index === 'number' ? base.nth(index) : base; + }, + calendar: (page: Page) => page.locator('[data-ui-name="MonthDateRangeComparator.Calendar"]'), + weekDaysRow: (page: Page) => page.locator('[data-ui-name="CalendarWeekDays"]'), + divider: (page: Page) => page.locator('[data-ui-name="Divider"]'), + cells: (page: Page, index?: number) => { + const base = page.getByRole('gridcell'); + return typeof index === 'number' ? base.nth(index) : base; + }, + dateRangeHeader: (page: Page) => page.locator('[data-ui-name="MonthDateRangeComparator.Header"]'), + inputValue: (page: Page) => page.locator('[data-ui-name="MonthDateRangeComparator.ValueDateRange"]'), + compareValue: (page: Page) => page.locator( + '[data-ui-name="MonthDateRangeComparator.CompareDateRange"]'), + popper: (page: Page) => page.getByRole('dialog'), + title: (page: Page) => page.locator('[data-ui-name="MonthDateRangeComparator.Title"]'), + period: (page: Page) => page.locator('[data-ui-name="MonthDateRangeComparator.Periods.Options"]'), + periodButtons: (page: Page) => page.getByRole('option'), + +}; + +/* ===================================================== +@visual +Visual states, hover and focus styles, paddings, margins, and snapshots. +===================================================== */ +test.describe(`${TAG.VISUAL}`, () => { + test.describe('MonthRangeComparator range', () => { + test('Verify month range comparator styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); + + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + + await test.step('Verify header and calendar styles', async () => { + await checkStyle(locators.dateRangeHeader(page), { padding: '16px' }); + + const indicstors = page.locator('[data-ui-name="DateRange.Indicator"]'); + const count = await indicstors.count(); + for (let i = 0; i < count; i++) { + const calendar = indicstors.nth(i); + await expect(calendar).toHaveAttribute('width', '16'); + await expect(calendar).toHaveAttribute('height', '16'); + await checkStyle(calendar, { + paddingLeft: '8px', + paddingRight: '8px', + }); + } + }); - await test.step('Verify popper attributes', async () => { - await expect(popper).toHaveAttribute('tabindex', '0'); - await expect(popper).toHaveAttribute('role', 'dialog'); - await expect(popper).toHaveAttribute('data-popper-placement', 'bottom-start'); - }); + await test.step('Verify style of available date', async () => { + const cell = locators.cells(page, 2); + await checkStyle(cell, { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - await test.step('Verify popper input attributes', async () => { - const inputValue = page.locator('[data-ui-name="MonthDateRangeComparator.ValueDateRange"]'); - await expect(inputValue.first()).toHaveAttribute('aria-label', 'Date field'); + await locators.cells(page, 10).click(); + await locators.cells(page, 11).click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + + await test.step('Verify style of selected date', async () => { + const selectedCell = page + .locator('[data-ui-name="CalendarMonths.Unit"][class*="Selected"]') + .nth(0); + await checkStyle(selectedCell, { + margin: '4px 0px 0px', + width: '60px', + height: '32px', + }); + }); - const compareValue = page.locator( - '[data-ui-name="MonthDateRangeComparator.CompareDateRange"]', - ); - await expect(compareValue.first()).toHaveAttribute('aria-label', 'Date field'); - await expect(compareValue.first()).toHaveAttribute('disabled', ''); + await test.step('Verify style for Apply picker button', async () => { + await checkStyle(locators.button(page, 'Apply'), { + color: 'rgb(255, 255, 255)', + backgroundColor: 'rgb(0, 143, 248)', + }); + }); + }); + test('Month range comparator filled state', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); + + const toggle = page.locator('[data-ui-name="MonthDateRangeComparator.CompareToggle"]'); + + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await locators.inputValue(page).nth(2).fill('05.2022'); + await locators.inputValue(page).nth(3).fill('08.2022'); + await toggle.click(); + await locators.compareValue(page).nth(2).fill('06.2022'); + await locators.compareValue(page).nth(3).fill('10.2022'); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + await expect(page).toHaveScreenshot(); + + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); + }); + }); + test.describe('Month Range comparator with advanced use', () => { + test('Verify mouse intearctions and styles of advanced use', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/month_range_comparator_advanced_use.tsx', 'en'); - const checkbox = page.locator('[data-ui-name="Checkbox.Value"]'); - await expect(checkbox).toHaveAttribute('type', 'checkbox'); - await expect(checkbox).toHaveAttribute('aria-invalid', 'false'); + const from = page.locator('[data-ui-name="MonthDateRangeComparator.ValueDateRange"]').first(); + const to = page.locator('[data-ui-name="MonthDateRangeComparator.CompareDateRange"]').first(); + const toggle = page.locator('[data-ui-name="MonthDateRangeComparator.CompareToggle"]'); - const inputsValue = page.locator( - 'input[data-ui-name="MonthDateRangeComparator.ValueDateRange"]', - ); - const count = await inputsValue.count(); + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - for (let i = 0; i < count; i++) { - const input = inputsValue.nth(i); - await expect(input).toHaveAttribute('type', 'text'); - await expect(input).toHaveAttribute('inputmode', 'numeric'); - await expect(input).toHaveAttribute('aria-invalid', 'false'); - } + await from.click(); + await locators.inputValue(page).nth(2).fill('052022'); + await locators.inputValue(page).nth(3).fill('072022'); - const compareValueInputs = page.locator( - 'input[data-ui-name="MonthDateRangeComparator.CompareDateRange"]', - ); - const count1 = await compareValueInputs.count(); - - for (let i = 0; i < count1; i++) { - const input = compareValueInputs.nth(i); - await expect(input).toHaveAttribute('type', 'text'); - await expect(input).toHaveAttribute('inputmode', 'numeric'); - await expect(input).toHaveAttribute('aria-invalid', 'false'); - } - - const calendars = page.locator('[data-name="Calendar"]'); - const count2 = await calendars.count(); - - for (let i = 0; i < count2; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('aria-hidden', 'true'); - } - }); + await toggle.click(); + await to.click(); + await locators.compareValue(page).nth(2).fill('012023'); + await locators.compareValue(page).nth(3).fill('082023'); - await test.step('Verify calendar header attributes', async () => { - const headPrev = page.locator('[data-ui-name="MonthDateRangeComparator.Prev"]'); - await expect(headPrev).toHaveAttribute('type', 'button'); - await expect(headPrev).toHaveAttribute('aria-label', 'Previous year'); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); - const headTitle = page.locator('[data-ui-name="MonthDateRangeComparator.Title"]'); - await expect(headTitle.first()).toHaveAttribute('aria-live', 'polite'); - await expect(headTitle.nth(1)).toHaveAttribute('aria-live', 'polite'); + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - const headNext = page.locator('[data-ui-name="MonthDateRangeComparator.Next"]'); - await expect(headNext).toHaveAttribute('type', 'button'); - await expect(headNext).toHaveAttribute('aria-label', 'Next year'); + await expect(page).toHaveScreenshot(); }); + }); +}); - await test.step('Verify calendar attributes', async () => { - const calendars = page.locator('[data-ui-name="MonthDateRangeComparator.Calendar"]'); - const count = await calendars.count(); +/* ===================================================== +@functional +Keyboard and mouse interactions - no snapshots here. +We verify states, visibility, and attributes. +===================================================== */ +test.describe(`${TAG.FUNCTIONAL}`, () => { + test.describe('MonthRangeComparator range', () => { + test('Verify roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); + + await test.step('Verify trigger attributes', async () => { + await expect(locators.monthRangeComparatorPickerTrigger(page)).toHaveAttribute('tabindex', '0'); + await expect(locators.monthRangeComparatorPickerTrigger(page)).toHaveAttribute('aria-haspopup', 'dialog'); + await expect(locators.monthRangeComparatorPickerTrigger(page)).toHaveAttribute('role', 'button'); + await expect(locators.monthRangeComparatorPickerTrigger(page)).toHaveAttribute('type', 'button'); + }); - for (let i = 0; i < count; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('role', 'grid'); - await expect(calendar).toHaveAttribute('disabled', ''); - } - }); + await test.step('Verify trigger svg attributes', async () => { + const svg = locators.monthRangeComparatorPickerTrigger(page).locator('svg'); + await expect(svg).toHaveAttribute('tabindex', '-1'); + await expect(svg).toHaveAttribute('aria-hidden', 'true'); + await expect(svg).toHaveAttribute('width', '16'); + await expect(svg).toHaveAttribute('height', '16'); + }); - await test.step('Verify days attributes', async () => { - const cells = page.locator('[data-ui-name="CalendarMonths.Unit"]'); - const cellCount = await cells.count(); + // Trigger click to open the popper + locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); + await test.step('Verify popper attributes', async () => { + await expect(locators.popper(page)).toHaveAttribute('tabindex', '0'); + await expect(locators.popper(page)).toHaveAttribute('data-popper-placement', 'bottom-start'); + }); - // Skip empty cells without aria-label - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; + await test.step('Verify popper input attributes', async () => { + await expect(locators.inputValue(page).first()).toHaveAttribute('aria-label', 'Date field'); - await expect(cell).toHaveAttribute('role', 'gridcell'); - await expect(cell).toHaveAttribute('aria-colindex'); - await expect(cell).toHaveAttribute('aria-rowindex'); + await expect(locators.compareValue(page).first()).toHaveAttribute('aria-label', 'Date field'); + await expect(locators.compareValue(page).first()).toHaveAttribute('disabled', ''); - const date = new Date(ariaLabel); - const month = date.getMonth(); - const isCurrentMonth = month === 5; + const checkbox = page.locator('[data-ui-name="Checkbox.Value"]'); + await expect(checkbox).toHaveAttribute('type', 'checkbox'); + await expect(checkbox).toHaveAttribute('aria-invalid', 'false'); - const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + const count = await page.getByRole('textbox').count(); - if (isCurrentMonth) { - expect(hasDisabledAttr).toBe(false); - expect(ariaDisabled).toBe('false'); + for (let i = 0; i < count; i++) { + const input = page.getByRole('textbox').nth(i); + await expect(input).toHaveAttribute('type', 'text'); + await expect(input).toHaveAttribute('inputmode', 'numeric'); + await expect(input).toHaveAttribute('aria-invalid', 'false'); } + }); - const text = await cell.textContent(); - expect(text?.trim()).not.toBe(''); - } - }); + await test.step('Verify calendar attributes', async () => { + const count = await locators.calendar(page).count(); + + for (let i = 0; i < count; i++) { + const calendar = locators.calendar(page).nth(i); + await expect(calendar).toHaveAttribute('role', 'grid'); + await expect(calendar).toHaveAttribute('disabled', ''); + } + }); - const period = page.locator('[data-ui-name="MonthDateRangeComparator.Periods.Options"]'); + await test.step('Verify days attributes', async () => { + const cells = page.locator('[data-ui-name="CalendarMonths.Unit"]'); + const cellCount = await cells.count(); - await test.step('Verify Period attributes', async () => { - await expect(period).toHaveAttribute('role', 'listbox'); - await expect(period).toHaveAttribute('aria-label', 'Presets'); - }); + for (let i = 0; i < cellCount; i++) { + const cell = cells.nth(i); - const periodButtons = page.locator( - '[data-ui-name="MonthDateRangeComparator.Periods.Options"] button', - ); + // Skip empty cells without aria-label + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; - await test.step('Verify Period buttons attributes', async () => { - const count = await periodButtons.count(); + await expect(cell).toHaveAttribute('role', 'gridcell'); + await expect(cell).toHaveAttribute('aria-colindex'); + await expect(cell).toHaveAttribute('aria-rowindex'); - for (let i = 0; i < count; i++) { - const button = periodButtons.nth(i); - await expect(button).toHaveAttribute('type', 'button'); - await expect(button).toHaveAttribute('role', 'option'); - } - }); + const date = new Date(ariaLabel); + const month = date.getMonth(); + const isCurrentMonth = month === 5; - await test.step('Verify Apply button attributes', async () => { - const apply = page.locator('[data-ui-name="MonthDateRangeComparator.Apply"]'); - await expect(apply).toHaveAttribute('type', 'button'); - }); + const hasDisabledAttr = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - await test.step('Verify Reset button attributes', async () => { - const reset = page.locator('[data-ui-name="MonthDateRangeComparator.Reset"]'); - await expect(reset).toHaveAttribute('type', 'button'); - }); - }); + if (isCurrentMonth) { + expect(hasDisabledAttr).toBe(false); + expect(ariaDisabled).toBe('false'); + } - test('Verify month range comparator styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const trigger = page.locator('[data-ui-name="MonthDateRangeComparator.Trigger"]'); - const header = page.locator('[data-ui-name="MonthDateRangeComparator.Header"]'); - const calendars = page.locator('[data-name="Calendar"]'); - const cells = page.locator('[data-ui-name="CalendarMonths.Unit"]'); - const apply = page.locator('[data-ui-name="MonthDateRangeComparator.Apply"]'); - - const checkStyle = async (element: any, expectedStyles: Record) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; - - await trigger.click(); - await page.waitForTimeout(300); - - await test.step('Verify header and calendar styles', async () => { - await checkStyle(header, { padding: '16px' }); - - const count = await calendars.count(); - for (let i = 0; i < count; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('width', '16'); - await expect(calendar).toHaveAttribute('height', '16'); - await checkStyle(calendar, { - paddingLeft: '8px', - paddingRight: '8px', - }); - } - }); + const text = await cell.textContent(); + expect(text?.trim()).not.toBe(''); + } + }); + + const period = page.locator('[data-ui-name="MonthDateRangeComparator.Periods.Options"]'); - await test.step('Verify style of available date', async () => { - const cell = cells.nth(2); - await checkStyle(cell, { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', + await test.step('Verify Period attributes', async () => { + await expect(period).toHaveAttribute('role', 'listbox'); + await expect(period).toHaveAttribute('aria-label', 'Presets'); }); }); - await cells.nth(10).click(); - await cells.nth(11).click(); - await apply.click(); + test('Month range comparator mouse interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); - await trigger.click(); + const buttons = page.locator('[data-ui-name="Button"]'); + const toggle = page.locator('[data-ui-name="MonthDateRangeComparator.CompareToggle"]'); - await test.step('Verify style of selected date', async () => { - const selectedCell = page - .locator('[data-ui-name="CalendarMonths.Unit"][class*="Selected"]') - .nth(0); - await checkStyle(selectedCell, { - margin: '4px 0px 0px', - width: '60px', - height: '32px', - }); - }); + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Verify style for Apply picker button', async () => { - await checkStyle(apply, { - color: 'rgb(255, 255, 255)', - backgroundColor: 'rgb(0, 143, 248)', - }); - }); - }); + const initialTitle1 = await locators.title(page).first().textContent(); + const initialTitle2 = await locators.title(page).nth(1).textContent(); - function formatAriaLabelToInputValue(ariaLabel: string | null): string { - if (!ariaLabel) { - throw new Error('aria-label is null'); - } + await locators.button(page, 'Previous year').click(); - const parsedDate = new Date(ariaLabel); + await expect(locators.title(page).first()).not.toHaveText(initialTitle1!); + await expect(locators.title(page).nth(1)).not.toHaveText(initialTitle2!); - if (isNaN(parsedDate.getTime())) { - throw new Error(`Invalid aria-label date: ${ariaLabel}`); - } + await locators.button(page, 'Next year').click(); + await expect(locators.title(page).first()).toHaveText(initialTitle1!); + await expect(locators.title(page).nth(1)).toHaveText(initialTitle2!); - const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); - const day = parsedDate.getDate().toString().padStart(2, '0'); - const year = parsedDate.getFullYear().toString(); + await locators.cells(page, 10).click(); + const inputValue_1 = await locators.inputValue(page).nth(2).inputValue(); + const inputValue_2 = await locators.inputValue(page).nth(3).inputValue(); + const calendarAriaLabel = await locators.cells(page, 10).getAttribute('aria-label'); + const expectedInputValue = formatAriaLabelToInputValue(calendarAriaLabel); - return `${month}/${year}`; - } + await expect(inputValue_1).toBe(expectedInputValue); + await expect(inputValue_2).toBe(''); - test('Month range comparator mouse interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await locators.cells(page, 15).click(); + const inputValue_22 = await locators.inputValue(page).nth(3).inputValue(); - await page.setContent(htmlContent); + const calendarAriaLabel22 = await locators.cells(page, 15).getAttribute('aria-label'); + const expectedInputValue22 = formatAriaLabelToInputValue(calendarAriaLabel22); + await expect(inputValue_22).toBe(expectedInputValue22); - const datePicker = await page.locator('[data-ui-name="MonthDateRangeComparator.Trigger"]'); - const popper = page.locator('[data-ui-name="MonthDateRangeComparator.Popper"]'); - const headPrev = page.locator('[data-ui-name="MonthDateRangeComparator.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthDateRangeComparator.Title"]'); - const headNext = page.locator('[data-ui-name="MonthDateRangeComparator.Next"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const inputFrom = page.locator('input[data-ui-name="MonthDateRangeComparator.ValueDateRange"]'); - const inputTo = page.locator('input[data-ui-name="MonthDateRangeComparator.CompareDateRange"]'); - const toggle = page.locator('[data-ui-name="MonthDateRangeComparator.CompareToggle"]'); - const apply = page.locator('[data-ui-name="MonthDateRangeComparator.Apply"]'); - const reset = page.locator('[data-ui-name="MonthDateRangeComparator.Reset"]'); + await locators.cells(page, 15).click(); + await page.waitForTimeout(300); + const inputValue15_1 = await locators.inputValue(page).nth(2).inputValue(); + const inputValue15_2 = await locators.inputValue(page).nth(3).inputValue(); - await datePicker.click(); - await expect(popper).toBeVisible(); - await page.waitForTimeout(300); - await datePicker.click(); - await expect(popper).not.toBeVisible(); - await page.waitForTimeout(100); - - await datePicker.click(); - await page.waitForTimeout(300); - - const initialTitle1 = await headTitle.first().textContent(); - const initialTitle2 = await headTitle.nth(1).textContent(); - - await headPrev.click(); - - await expect(headTitle.first()).not.toHaveText(initialTitle1!); - await expect(headTitle.nth(1)).not.toHaveText(initialTitle2!); - - await headNext.click(); - await expect(headTitle.first()).toHaveText(initialTitle1!); - await expect(headTitle.nth(1)).toHaveText(initialTitle2!); - - const cells = page.locator('[role="gridcell"]'); - - await cells.nth(10).click(); - const inputValue_1 = await inputFrom.nth(0).inputValue(); - const inputValue_2 = await inputFrom.nth(1).inputValue(); - const calendarAriaLabel = await cells.nth(10).getAttribute('aria-label'); - const expectedInputValue = formatAriaLabelToInputValue(calendarAriaLabel); - - await expect(inputValue_1).toBe(expectedInputValue); - await expect(inputValue_2).toBe(''); - - await expect(popper).toBeVisible(); - await cells.nth(15).click(); - const inputValue_22 = await inputFrom.nth(1).inputValue(); - - const calendarAriaLabel22 = await cells.nth(15).getAttribute('aria-label'); - const expectedInputValue22 = formatAriaLabelToInputValue(calendarAriaLabel22); - await expect(inputValue_22).toBe(expectedInputValue22); - - await expect(popper).toBeVisible(); - - await cells.nth(15).click(); - await page.waitForTimeout(300); - const inputValue15_1 = await inputFrom.nth(0).inputValue(); - const inputValue15_2 = await inputFrom.nth(1).inputValue(); - - await expect(inputValue15_1).toBe(expectedInputValue22); - await expect(inputValue15_2).toBe(''); - - await cells.nth(15).click(); - const inputValue_15_3 = await inputFrom.nth(0).inputValue(); - const inputValue15_3 = await inputFrom.nth(1).inputValue(); - await expect(inputValue_15_3).toBe(expectedInputValue22); - await expect(inputValue15_3).toBe(expectedInputValue22); - - await toggle.click(); - - await cells.nth(5).click(); - const inputValueTo_1 = await inputTo.nth(0).inputValue(); - const inputValueTo_2 = await inputTo.nth(1).inputValue(); - - const calendarAriaLabel_1 = await cells.nth(5).getAttribute('aria-label'); - const expectedInputValue50 = formatAriaLabelToInputValue(calendarAriaLabel_1); - - await expect(inputValueTo_1).toBe(expectedInputValue50); - await expect(inputValueTo_2).toBe(''); - - await cells.nth(8).click(); - - const inputValueTo_11 = await inputTo.nth(0).inputValue(); - const inputValueTo_21 = await inputTo.nth(1).inputValue(); - - const calendarAriaLabel_2 = await cells.nth(8).getAttribute('aria-label'); - const expectedInputValue55 = formatAriaLabelToInputValue(calendarAriaLabel_2); - - await expect(inputValueTo_11).toBe(expectedInputValue50); - await expect(inputValueTo_21).toBe(expectedInputValue55); - - await apply.click(); - await expect(popper).not.toBeVisible(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).not.toHaveText( - 'Select date ranges', - ); - - await datePicker.click(); - await page.waitForTimeout(200); - await reset.click(); - await expect(popper).not.toBeVisible(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).toHaveText( - 'Select date ranges', - ); - - await datePicker.click(); - await page.waitForTimeout(200); - await buttons.nth(1).click(); - await expect(popper).toBeVisible(); - await apply.click(); - await expect(popper).not.toBeVisible(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).not.toHaveText( - 'Select date ranges', - ); - - await datePicker.click(); - await page.waitForTimeout(200); - await inputFrom.first().fill('05.2022'); - await inputFrom.nth(1).fill('08.2022'); - await toggle.click(); - await inputTo.first().fill('06.2022'); - await inputTo.nth(1).fill('10.2022'); - await apply.click(); - await page.waitForTimeout(100); - await expect(page).toHaveScreenshot(); - - await datePicker.click(); - await page.waitForTimeout(200); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); - }); + await expect(inputValue15_1).toBe(expectedInputValue22); + await expect(inputValue15_2).toBe(''); - test('Month range comparator keyboard interactions', async ({ page, browserName }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePicker = page.locator('[data-ui-name="MonthDateRangeComparator.Trigger"]'); - const popper = page.locator('[data-ui-name="MonthDateRangeComparator.Popper"]'); - const headPrev = page.locator('[data-ui-name="MonthDateRangeComparator.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthDateRangeComparator.Title"]'); - const headNext = page.locator('[data-ui-name="MonthDateRangeComparator.Next"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const inputFrom = page.locator('input[data-ui-name="MonthDateRangeComparator.ValueDateRange"]'); - const inputTo = page.locator('input[data-ui-name="MonthDateRangeComparator.CompareDateRange"]'); - const apply = page.locator('[data-ui-name="MonthDateRangeComparator.Apply"]'); - const reset = page.locator('[data-ui-name="MonthDateRangeComparator.Reset"]'); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await datePicker.hover(); - await expect(page).toHaveScreenshot(); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); - await expect(popper).toBeVisible(); - - await expect(datePicker).not.toBeFocused(); - await expect(popper).toBeFocused(); - - await page.keyboard.press('Escape'); - await expect(popper).not.toBeVisible(); - - await page.keyboard.press('Space'); - await page.waitForTimeout(300); - await expect(popper).toBeVisible(); - await expect(datePicker.first()).not.toBeFocused(); - await expect(popper).toBeFocused(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page.getByLabel('To Date field').first()).toBeFocused(); - - if (browserName === 'webkit') return; // works not ctable in test browser - - await page.keyboard.press('Tab'); - await expect(page.locator('[data-ui-name="Checkbox.Value"]')).toBeFocused(); - - const [initialTitleFrom, initialTitleTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); // space doesn't work - bug! - await page.waitForTimeout(50); - - const [titleAfterFirstEnterFrom, titleAfterFirstEnterTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); - - expect(titleAfterFirstEnterFrom).not.toBe(initialTitleFrom); - expect(titleAfterFirstEnterTo).not.toBe(initialTitleTo); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(headNext).toBeFocused(); - - await page.keyboard.press('Enter'); // space doesn't work - bug! - await page.waitForTimeout(50); - - const [titleAfterSecondEnterFrom, titleAfterSecondEnterTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); - expect(titleAfterSecondEnterFrom).toBe(initialTitleFrom); - expect(titleAfterSecondEnterTo).toBe(initialTitleTo); - - await page.keyboard.press('Shift+Tab'); - await expect( - page.locator('[data-ui-name="MonthDateRangeComparator.Calendar"]').first(), - ).toBeFocused(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.waitForTimeout(50); - await expect(buttons.first()).toBeFocused(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.waitForTimeout(50); - await expect(apply).toBeFocused(); - - await page.keyboard.press('Tab'); - await expect(reset).toBeFocused(); - - await page.keyboard.press('Tab'); - await expect(popper).toBeFocused(); - - const [initialFrom1, initialFrom2] = await Promise.all([ - inputFrom.nth(0).inputValue(), - inputFrom.nth(1).inputValue(), - ]); - - await page.keyboard.press('ArrowLeft'); - - const [afterLeftFrom1, afterLeftFrom2] = await Promise.all([ - inputFrom.nth(0).inputValue(), - inputFrom.nth(1).inputValue(), - ]); - - expect(afterLeftFrom1).toBe(initialFrom1); - expect(afterLeftFrom2).toBe(initialFrom2); - - await page.keyboard.press('ArrowUp'); - await page.keyboard.press('Space'); - await page.waitForTimeout(50); - - const [afterUpFrom1, afterUpFrom2] = await Promise.all([ - inputFrom.nth(0).inputValue(), - inputFrom.nth(1).inputValue(), - ]); + await locators.cells(page, 15).click(); + const inputValue_15_3 = await locators.inputValue(page).nth(2).inputValue(); + const inputValue15_3 = await locators.inputValue(page).nth(3).inputValue(); + await expect(inputValue_15_3).toBe(expectedInputValue22); + await expect(inputValue15_3).toBe(expectedInputValue22); - expect(afterUpFrom1).not.toBe(afterLeftFrom1); - expect(afterUpFrom2).toBe(afterLeftFrom2); - - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Space'); - await page.waitForTimeout(100); - - const [afterRightFrom1, afterRightFrom2] = await Promise.all([ - inputFrom.nth(0).inputValue(), - inputFrom.nth(1).inputValue(), - ]); + await toggle.click(); - expect(afterRightFrom1).toBe(afterUpFrom1); - expect(afterRightFrom2).not.toBe(afterUpFrom2); - - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('Shift+Tab'); - - await page.keyboard.press('Space'); - await page.waitForTimeout(100); - - await page.keyboard.press('Tab'); - await expect( - page.locator('[data-ui-name="MonthDateRangeComparator.CompareDateRange"]').nth(2), - ).toBeFocused(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(headPrev).toBeFocused(); - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - - await page.keyboard.press('Enter'); - await page.keyboard.press('ArrowLeft'); - - const [initialTo1, initialTo2] = await Promise.all([ - inputTo.nth(0).inputValue(), - inputTo.nth(1).inputValue(), - ]); - - await page.keyboard.press('ArrowUp'); - await page.keyboard.press('Space'); - - const [afterUpTo1, afterUpTo2] = await Promise.all([ - inputTo.nth(0).inputValue(), - inputTo.nth(1).inputValue(), - ]); - - expect(afterUpTo1).not.toBe(initialTo1); - expect(afterUpTo2).toBe(initialTo2); - - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Space'); - await page.waitForTimeout(50); - - const [afterRightTo1, afterRightTo2] = await Promise.all([ - inputTo.nth(0).inputValue(), - inputTo.nth(1).inputValue(), - ]); - - expect(afterRightTo1).toBe(afterUpTo1); - expect(afterRightTo2).not.toBe(afterUpTo2); + await locators.cells(page, 5).click(); + const inputValueTo_1 = await locators.compareValue(page).nth(2).inputValue(); + const inputValueTo_2 = await locators.compareValue(page).nth(3).inputValue(); - const [finalFrom1, finalFrom2] = await Promise.all([ - inputFrom.nth(0).inputValue(), - inputFrom.nth(1).inputValue(), - ]); + const calendarAriaLabel_1 = await locators.cells(page, 5).getAttribute('aria-label'); + const expectedInputValue50 = formatAriaLabelToInputValue(calendarAriaLabel_1); - expect(finalFrom1).toBe(afterRightFrom1); - expect(finalFrom2).toBe(afterRightFrom2); + await expect(inputValueTo_1).toBe(expectedInputValue50); + await expect(inputValueTo_2).toBe(''); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); + await locators.cells(page, 8).click(); - await expect(apply).toBeFocused(); - await page.keyboard.press('Enter'); - await page.waitForTimeout(50); - await expect(popper).not.toBeVisible(); + const inputValueTo_11 = await locators.compareValue(page).nth(2).inputValue(); + const inputValueTo_21 = await locators.compareValue(page).nth(3).inputValue(); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).not.toHaveText( - 'Select date ranges', - ); + const calendarAriaLabel_2 = await locators.cells(page, 8).getAttribute('aria-label'); + const expectedInputValue55 = formatAriaLabelToInputValue(calendarAriaLabel_2); - await page.keyboard.press('Enter'); - await page.waitForTimeout(300); + await expect(inputValueTo_11).toBe(expectedInputValue50); + await expect(inputValueTo_21).toBe(expectedInputValue55); - for (let i = 0; i < 14; i++) await page.keyboard.press('Tab'); - await expect(reset).toBeFocused(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).not.toHaveText( + 'Select date ranges', + ); - await page.keyboard.press('Space'); - await page.waitForTimeout(300); + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await locators.button(page, 'Reset').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).toHaveText( + 'Select date ranges', + ); - await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).toHaveText( - 'Select date ranges', - ); - }); -}); + await locators.monthRangeComparatorPickerTrigger(page).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await buttons.nth(1).click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).not.toHaveText( + 'Select date ranges', + ); + }); -test.describe('Month Range comparator with advanced use', () => { - test('Verify mouse intearctions and styles of advanced use', async ({ page }) => { - const standPath = - 'stories/components/date-picker/docs/examples/month_range_comparator_advanced_use.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + test('Month range comparator keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page, browserName }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/date_range_comparator.tsx', 'en'); + const buttons = page.locator('[data-ui-name="Button"]'); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + + await expect(locators.monthRangeComparatorPickerTrigger(page)).not.toBeFocused(); + await expect(locators.popper(page)).toBeFocused(); + + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await expect(locators.popper(page)).toBeFocused(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page.getByLabel('To Date field').first()).toBeFocused(); + + await page.keyboard.press('Tab'); + await expect(page.locator('[data-ui-name="Checkbox.Value"]')).toBeFocused(); + + const [initialTitleFrom, initialTitleTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Enter'); + + const [titleAfterFirstEnterFrom, titleAfterFirstEnterTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); + + expect(titleAfterFirstEnterFrom).not.toBe(initialTitleFrom); + expect(titleAfterFirstEnterTo).not.toBe(initialTitleTo); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next year')).toBeFocused(); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Next year')).toBeFocused(); + await page.keyboard.press('Space'); + + const [titleAfterSecondEnterFrom, titleAfterSecondEnterTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); + expect(titleAfterSecondEnterFrom).toBe(initialTitleFrom); + expect(titleAfterSecondEnterTo).toBe(initialTitleTo); + + await page.keyboard.press('Shift+Tab'); + await expect( + page.locator('[data-ui-name="MonthDateRangeComparator.Calendar"]').first(), + ).toBeFocused(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.waitForTimeout(50); + await expect(buttons.first()).toBeFocused(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.waitForTimeout(50); + await expect(locators.button(page, 'Apply')).toBeFocused(); + + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Reset')).toBeFocused(); + + await page.keyboard.press('Tab'); + await expect(locators.popper(page)).toBeFocused(); + + const [initialFrom1, initialFrom2] = await Promise.all([ + locators.inputValue(page).nth(2).inputValue(), + locators.inputValue(page).nth(3).inputValue(), + ]); + + await page.keyboard.press('ArrowLeft'); + + const [afterLeftFrom1, afterLeftFrom2] = await Promise.all([ + locators.inputValue(page).nth(2).inputValue(), + locators.inputValue(page).nth(3).inputValue(), + ]); + + expect(afterLeftFrom1).toBe(initialFrom1); + expect(afterLeftFrom2).toBe(initialFrom2); + + await page.keyboard.press('ArrowUp'); + await page.keyboard.press('Space'); + await page.waitForTimeout(50); + + const [afterUpFrom1, afterUpFrom2] = await Promise.all([ + locators.inputValue(page).nth(2).inputValue(), + locators.inputValue(page).nth(3).inputValue(), + ]); + + expect(afterUpFrom1).not.toBe(afterLeftFrom1); + expect(afterUpFrom2).toBe(afterLeftFrom2); + + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Space'); + await page.waitForTimeout(100); + + const [afterRightFrom1, afterRightFrom2] = await Promise.all([ + locators.inputValue(page).nth(2).inputValue(), + locators.inputValue(page).nth(3).inputValue(), + ]); + + expect(afterRightFrom1).toBe(afterUpFrom1); + expect(afterRightFrom2).not.toBe(afterUpFrom2); + + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Shift+Tab'); + + await page.keyboard.press('Space'); + await page.waitForTimeout(100); + + await page.keyboard.press('Tab'); + await expect( + page.locator('[data-ui-name="MonthDateRangeComparator.CompareDateRange"]').nth(2), + ).toBeFocused(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Previous year')).toBeFocused(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + + await page.keyboard.press('Enter'); + await page.keyboard.press('ArrowLeft'); + + const [initialTo1, initialTo2] = await Promise.all([ + locators.compareValue(page).nth(2).inputValue(), + locators.compareValue(page).nth(3).inputValue(), + ]); + + await page.keyboard.press('ArrowUp'); + await page.keyboard.press('Space'); + + const [afterUpTo1, afterUpTo2] = await Promise.all([ + locators.compareValue(page).nth(2).inputValue(), + locators.compareValue(page).nth(3).inputValue(), + ]); + + expect(afterUpTo1).not.toBe(initialTo1); + expect(afterUpTo2).toBe(initialTo2); + + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Space'); + await page.waitForTimeout(50); + + const [afterRightTo1, afterRightTo2] = await Promise.all([ + locators.compareValue(page).nth(2).inputValue(), + locators.compareValue(page).nth(3).inputValue(), + ]); + + expect(afterRightTo1).toBe(afterUpTo1); + expect(afterRightTo2).not.toBe(afterUpTo2); - await page.setContent(htmlContent); + const [finalFrom1, finalFrom2] = await Promise.all([ + locators.inputValue(page).nth(2).inputValue(), + locators.inputValue(page).nth(3).inputValue(), + ]); - const datePicker = await page.locator('[data-ui-name="MonthDateRangeComparator.Trigger"]'); - const from = page.locator('[data-ui-name="MonthDateRangeComparator.ValueDateRange"]').first(); - const inputFrom = page.locator('input[data-ui-name="MonthDateRangeComparator.ValueDateRange"]'); - const to = page.locator('[data-ui-name="MonthDateRangeComparator.CompareDateRange"]').first(); - const inputTo = page.locator('input[data-ui-name="MonthDateRangeComparator.CompareDateRange"]'); - const toggle = page.locator('[data-ui-name="MonthDateRangeComparator.CompareToggle"]'); - const apply = page.locator('[data-ui-name="MonthDateRangeComparator.Apply"]'); + expect(finalFrom1).toBe(afterRightFrom1); + expect(finalFrom2).toBe(afterRightFrom2); - await page.keyboard.press('Tab'); - await page.keyboard.press('Enter'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); - await from.click(); - await inputFrom.first().fill('052022'); - await inputFrom.nth(1).fill('072022'); + await expect(locators.button(page, 'Apply')).toBeFocused(); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).not.toHaveText( + 'Select date ranges', + ); - await toggle.click(); - await to.click(); - await inputTo.first().fill('012023'); - await inputTo.nth(1).fill('082023'); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await apply.click(); + for (let i = 0; i < 14; i++) await page.keyboard.press('Tab'); + await expect(locators.button(page, 'Reset')).toBeFocused(); - await datePicker.click(); - await page.waitForTimeout(300); - await expect(page).toHaveScreenshot(); + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + await expect(page.locator('[data-ui-name="LinkTrigger.Text"]').nth(1)).toHaveText( + 'Select date ranges', + ); + }); }); }); diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/Month-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-Month-Range-comparator-with-advanced-u-22177-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/Month-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-Month-Range-comparator-with-advanced-u-22177-mouse-intearctions-and-styles-of-advanced-use-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/Month-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-Month-Range-comparator-with-advanced-u-22177-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/Month-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-Month-Range-comparator-with-advanced-u-22177-mouse-intearctions-and-styles-of-advanced-use-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/Month-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-Month-Range-comparator-with-advanced-u-22177-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/Month-Range-comparator-with-advanced-use-Verify-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-Month-Range-comparator-with-advanced-u-22177-mouse-intearctions-and-styles-of-advanced-use-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-1-chromium-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-1-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-1-firefox-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-1-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-1-webkit-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-1-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-2-chromium-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-2-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-2-firefox-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-2-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-2-webkit-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-mouse-interactions-2-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/-visual-MonthRangeComparator-range-Month-range-comparator-filled-state-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-chromium-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-chromium-linux.png deleted file mode 100644 index 5f5a7d96a4..0000000000 Binary files a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-firefox-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-firefox-linux.png deleted file mode 100644 index 91b4bba01a..0000000000 Binary files a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-firefox-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-webkit-linux.png b/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-webkit-linux.png deleted file mode 100644 index dbce3d416b..0000000000 Binary files a/semcore/date-picker/__tests__/month-range-comparator.browser-test.tsx-snapshots/MonthRangeComparator-range-Month-range-comparator-keyboard-interactions-1-webkit-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx index 4593ea553a..6024372f9c 100644 --- a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx +++ b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx @@ -1,667 +1,551 @@ -import { e2eStandToHtml } from '@semcore/testing-utils/e2e-stand'; import { expect, test } from '@semcore/testing-utils/playwright'; +import type { Page } from '@semcore/testing-utils/playwright'; +import { loadPage } from '@semcore/testing-utils/shared/helpers'; +import { TAG } from '@semcore/testing-utils/shared/tags'; -test.describe('Month Range Trigger', () => { - test('Verify trigger when entering date manually', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - - await page.setContent(htmlContent); - - const datePicker = await page.locator('[data-ui-name="MonthRangePicker.Trigger"]'); - const screenshotsClip = (await datePicker.nth(1).boundingBox())!; - screenshotsClip.x -= 4; - screenshotsClip.y -= 4; - screenshotsClip.width += 8; - screenshotsClip.height += 8; - - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.type('052020'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.type('05'); - await page.keyboard.type('2024'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - await page.keyboard.press('Shift+Tab'); - await page.keyboard.press('Shift+Tab'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - - await page.keyboard.press('Tab'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await page.keyboard.press('Backspace'); - await expect(page).toHaveScreenshot({ clip: screenshotsClip }); - }); - - test('Verify trigger states and props', async ({ page }) => { - const standPath = 'stories/components/date-picker/tests/examples/month-range-trigger.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); +export function formatAriaLabelToInputValue(ariaLabel: string | null): string { + if (!ariaLabel) { + throw new Error('aria-label is null'); + } - await page.setContent(htmlContent); + let parsedDate = new Date(ariaLabel); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); + if (isNaN(parsedDate.getTime())) { + parsedDate = new Date(`${ariaLabel} 1`); + } - await expect(page).toHaveScreenshot(); + if (isNaN(parsedDate.getTime())) { + throw new Error(`Invalid aria-label date: ${ariaLabel}`); + } - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await page.keyboard.press('Tab'); - await expect(page).toHaveScreenshot(); + const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); + const year = parsedDate.getFullYear().toString(); + + return `${month}/${year}`; +} + +export const locators = { + + button: (page: Page, name?: string, index?: number) => { + const base = page.getByRole('button', { name }); + return typeof index === 'number' ? base.nth(index) : base; + }, + + monthRangePickerTrigger: (page: Page, index?: number) => { + const base = page.locator('[data-ui-name="MonthRangePicker.Trigger"]'); + return typeof index === 'number' ? base.nth(index) : base; + }, + calendar: (page: Page) => page.locator('[data-ui-name="MonthRangePicker.Calendar"]'), + weekDaysRow: (page: Page) => page.locator('[data-ui-name="CalendarWeekDays"]'), + divider: (page: Page) => page.locator('[data-ui-name="Divider"]'), + cells: (page: Page, index?: number) => { + const base = page.getByRole('gridcell'); + return typeof index === 'number' ? base.nth(index) : base; + }, + dateRangeHeader: (page: Page) => page.locator('[data-ui-name="MonthRangePicker.Header"]'), + inputValue: (page: Page) => page.locator('[data-ui-name="MonthRangePicker.ValueDateRange"]'), + compareValue: (page: Page) => page.locator( + '[data-ui-name="MonthRangePicker.CompareDateRange"]'), + popper: (page: Page) => page.getByRole('dialog'), + title: (page: Page) => page.locator('[data-ui-name="MonthRangePicker.Title"]'), + period: (page: Page) => page.locator('[data-ui-name="MonthRangePicker.Period"]'), + periodButtons: (page: Page) => page.getByRole('option'), + +}; + +/* ===================================================== +@visual +Visual states, hover and focus styles, paddings, margins, and snapshots. +===================================================== */ +test.describe(`${TAG.VISUAL}`, () => { + test.describe('Month Range Trigger', () => { + test('Verify trigger when entering date manually', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + + const screenshotsClip = (await locators.monthRangePickerTrigger(page, 1).boundingBox())!; + screenshotsClip.x -= 4; + screenshotsClip.y -= 4; + screenshotsClip.width += 8; + screenshotsClip.height += 8; + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.type('052020'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.type('05'); + await page.keyboard.type('2024'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + await page.keyboard.press('Shift+Tab'); + await page.keyboard.press('Shift+Tab'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + + await page.keyboard.press('Tab'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Backspace'); + await page.keyboard.press('Backspace'); + await page.keyboard.press('Backspace'); + await page.keyboard.press('Backspace'); + await page.keyboard.press('Backspace'); + await expect(page).toHaveScreenshot({ clip: screenshotsClip }); + }); + + test('Verify trigger states and props', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/tests/examples/month-range-trigger.tsx', 'en'); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + + await expect(page).toHaveScreenshot(); + + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await page.keyboard.press('Tab'); + await expect(page).toHaveScreenshot(); + }); }); -}); + test.describe('Month range', () => { + test('Verify Month RangePicker styles', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + + const separator = page.locator('[data-ui-name="DateRange.RangeSep"]'); + + const checkStyle = async (element: any, expectedStyles: Record) => { + for (const [property, expectedValue] of Object.entries(expectedStyles)) { + const actualValue = await element.evaluate( + (el: any, property: any) => getComputedStyle(el)[property], + property, + ); + expect(actualValue).toBe(expectedValue); + } + }; -test.describe('Month range', () => { - test('Verify roles and attributes', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/date_range_comparator.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); + await test.step('Verify SVG dimensions and paddings', async () => { + const svg = locators.monthRangePickerTrigger(page).locator('svg'); + await checkStyle(svg, { + paddingLeft: '8px', + paddingRight: '8px', + }); + await expect(svg).toHaveAttribute('width', '16'); + await expect(svg).toHaveAttribute('height', '16'); + }); - await page.setContent(htmlContent); + await test.step('Verify trigger separator padding', async () => { + await checkStyle(separator, { paddingRight: '8px' }); + }); - const datePickerTrigger = page.locator( - 'button[data-ui-name="MonthDateRangeComparator.Trigger"]', - ); + await test.step('Verify disabled date style', async () => { + await locators.monthRangePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Verify trigger attributes', async () => { - const attributes = [ - ['tabindex', '0'], - ['aria-haspopup', 'dialog'], - ['role', 'button'], - ['type', 'button'], - ]; + await checkStyle(locators.cells(page, 0), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - for (const [attr, value] of attributes) { - await expect(datePickerTrigger).toHaveAttribute(attr, value); - } - }); + await test.step('Verify available date style', async () => { + await checkStyle(locators.cells(page, 2), { + color: 'rgb(25, 27, 35)', + backgroundColor: 'rgb(255, 255, 255)', + margin: '4px 0px 0px', + }); + }); - await test.step('Verify trigger svg attributes', async () => { - const svg = datePickerTrigger.locator('svg'); - const svgAttributes = [ - ['tabindex', '-1'], - ['aria-hidden', 'true'], - ['width', '16'], - ['height', '16'], - ]; - - for (const [attr, value] of svgAttributes) { - await expect(svg).toHaveAttribute(attr, value); - } - }); + await test.step('Select range and open popper again', async () => { + await locators.cells(page, 10).click(); + await locators.cells(page, 11).click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); - await datePickerTrigger.click(); - const popper = page.locator('[data-ui-name="MonthDateRangeComparator.Popper"]'); + await locators.monthRangePickerTrigger(page, 0).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + }); - await test.step('Verify popper attributes', async () => { - const attributes = [ - ['role', 'dialog'], - ['data-popper-placement', 'bottom-start'], - ]; + const selectedCells = page.locator('[data-ui-name="CalendarMonths.Unit"][class*="Selected"]'); - for (const [attr, value] of attributes) { - await expect(popper).toHaveAttribute(attr, value); - } + await test.step('Verify selected date style', async () => { + await checkStyle(selectedCells.nth(0), { + margin: '4px 0px 0px', + width: '60px', + height: '32px', + }); + }); + + await test.step('Verify style for Apply picker button', async () => { + await checkStyle(locators.button(page, 'Apply'), { + color: 'rgb(255, 255, 255)', + backgroundColor: 'rgb(0, 143, 248)', + }); + }); }); + }); +}); +/* ===================================================== +@functional +Keyboard and mouse interactions - no snapshots here. +We verify states, visibility, and attributes. +===================================================== */ +test.describe(`${TAG.FUNCTIONAL}`, () => { + test.describe('Month range', () => { + test('Verify roles and attributes', { + tag: [TAG.PRIORITY_HIGH, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + + await test.step('Verify trigger svg attributes', async () => { + const svg = locators.monthRangePickerTrigger(page, 1).locator('svg'); + const svgAttributes = [ + ['tabindex', '-1'], + ['aria-hidden', 'true'], + ['width', '16'], + ['height', '16'], + ]; - await test.step('Verify popper input attributes', async () => { - const inputValue = page.locator('[data-ui-name="MonthDateRangeComparator.ValueDateRange"]'); - const compareValue = page.locator( - '[data-ui-name="MonthDateRangeComparator.CompareDateRange"]', - ); - const checkbox = page.locator('[data-ui-name="Checkbox.Value"]'); - - await expect(inputValue.first()).toHaveAttribute('aria-label', 'Date field'); - await expect(compareValue.first()).toHaveAttribute('aria-label', 'Date field'); - await expect(compareValue.first()).toHaveAttribute('disabled', ''); - - const checkboxAttributes = [ - ['type', 'checkbox'], - ['aria-invalid', 'false'], - ]; - for (const [attr, value] of checkboxAttributes) { - await expect(checkbox).toHaveAttribute(attr, value); - } - - const inputsValue = page.locator( - 'input[data-ui-name="MonthDateRangeComparator.ValueDateRange"]', - ); - const inputsCompare = page.locator( - 'input[data-ui-name="MonthDateRangeComparator.CompareDateRange"]', - ); - - const checkInputAttributes = async (locator: any, tabindex: string) => { - const count = await locator.count(); - for (let i = 0; i < count; i++) { - const input = locator.nth(i); - const attributes = [ - ['type', 'text'], - ['inputmode', 'numeric'], - ['aria-invalid', 'false'], - ]; - for (const [attr, value] of attributes) { - await expect(input).toHaveAttribute(attr, value); - } + for (const [attr, value] of svgAttributes) { + await expect(svg).toHaveAttribute(attr, value); } - }; + }); - const calendars = page.locator('[data-name="Calendar"]'); - const calendarCount = await calendars.count(); - for (let i = 0; i < calendarCount; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('aria-hidden', 'true'); - } - }); + await locators.monthRangePickerTrigger(page, 1).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Verify calendar header attributes', async () => { - const headPrev = page.locator('[data-ui-name="MonthDateRangeComparator.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthDateRangeComparator.Title"]'); - const headNext = page.locator('[data-ui-name="MonthDateRangeComparator.Next"]'); - - const prevAttributes = [ - ['type', 'button'], - ['aria-label', 'Previous year'], - ]; - const nextAttributes = [ - ['type', 'button'], - ['aria-label', 'Next year'], - ]; - - for (const [attr, value] of prevAttributes) { - await expect(headPrev).toHaveAttribute(attr, value); - } - - for (const [attr, value] of nextAttributes) { - await expect(headNext).toHaveAttribute(attr, value); - } - - await expect(headTitle.first()).toHaveAttribute('aria-live', 'polite'); - await expect(headTitle.nth(1)).toHaveAttribute('aria-live', 'polite'); - }); + await test.step('Verify calendar attributes', async () => { + const count = await locators.calendar(page).count(); - await test.step('Verify calendar attributes', async () => { - const calendars = page.locator('[data-ui-name="MonthDateRangeComparator.Calendar"]'); - const count = await calendars.count(); + for (let i = 0; i < count; i++) { + const calendar = locators.calendar(page).nth(i); + await expect(calendar).toHaveAttribute('role', 'grid'); + await expect(calendar).toHaveAttribute('disabled', ''); + } + }); - for (let i = 0; i < count; i++) { - const calendar = calendars.nth(i); - await expect(calendar).toHaveAttribute('role', 'grid'); - await expect(calendar).toHaveAttribute('disabled', ''); - } - }); + await test.step('Verify days attributes', async () => { + const cellCount = await locators.cells(page).count(); - await test.step('Verify days attributes', async () => { - const cells = page.locator('[data-ui-name="CalendarMonths.Unit"]'); - const cellCount = await cells.count(); + for (let i = 0; i < cellCount; i++) { + const cell = locators.cells(page, i); + const ariaLabel = await cell.getAttribute('aria-label'); + if (!ariaLabel) continue; - for (let i = 0; i < cellCount; i++) { - const cell = cells.nth(i); - const ariaLabel = await cell.getAttribute('aria-label'); - if (!ariaLabel) continue; + const attributes = ['role', 'aria-colindex', 'aria-rowindex']; + for (const attr of attributes) { + await expect(cell).toHaveAttribute(attr); + } - const attributes = ['role', 'aria-colindex', 'aria-rowindex']; - for (const attr of attributes) { - await expect(cell).toHaveAttribute(attr); - } + const date = new Date(ariaLabel); + const isCurrentMonth = date.getMonth() === 5; - const date = new Date(ariaLabel); - const isCurrentMonth = date.getMonth() === 5; + const hasDisabled = (await cell.getAttribute('disabled')) !== null; + const ariaDisabled = await cell.getAttribute('aria-disabled'); - const hasDisabled = (await cell.getAttribute('disabled')) !== null; - const ariaDisabled = await cell.getAttribute('aria-disabled'); + if (isCurrentMonth) { + expect(hasDisabled).toBe(false); + expect(ariaDisabled).toBe('false'); + } - if (isCurrentMonth) { - expect(hasDisabled).toBe(false); - expect(ariaDisabled).toBe('false'); + const text = await cell.textContent(); + expect(text?.trim()).not.toBe(''); } + }); - const text = await cell.textContent(); - expect(text?.trim()).not.toBe(''); - } - }); - - await test.step('Verify Period attributes', async () => { - const period = page.locator('[data-ui-name="MonthDateRangeComparator.Periods.Options"]'); - const attributes = [ - ['role', 'listbox'], - ['aria-label', 'Presets'], - ]; - for (const [attr, value] of attributes) { - await expect(period).toHaveAttribute(attr, value); - } - }); - - await test.step('Verify Period buttons attributes', async () => { - const periodButtons = page.locator( - '[data-ui-name="MonthDateRangeComparator.Periods.Options"] button', - ); - const count = await periodButtons.count(); - - for (let i = 0; i < count; i++) { - const button = periodButtons.nth(i); + await test.step('Verify Period attributes', async () => { const attributes = [ - ['type', 'button'], - ['role', 'option'], + ['role', 'listbox'], + ['aria-label', 'Presets'], ]; for (const [attr, value] of attributes) { - await expect(button).toHaveAttribute(attr, value); + await expect(locators.period(page)).toHaveAttribute(attr, value); } - } - }); - - await test.step('Verify Apply and Reset button attributes', async () => { - const apply = page.locator('[data-ui-name="MonthDateRangeComparator.Apply"]'); - const reset = page.locator('[data-ui-name="MonthDateRangeComparator.Reset"]'); - - const buttons = [apply, reset]; - for (const button of buttons) { - await expect(button).toHaveAttribute('type', 'button'); - } - }); - }); - - test('Verify Month RangePicker styles', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePickerTrigger = page.locator('[data-ui-name="MonthRangePicker.Trigger"]').first(); - const prevButton = page.locator('[data-ui-name="MonthRangePicker.Prev"]'); - const cells = page.locator('[data-ui-name="CalendarMonths.Unit"]'); - const applyButton = page.locator('[data-ui-name="MonthRangePicker.Apply"]'); - const separator = page.locator('[data-ui-name="DateRange.RangeSep"]'); - - const checkStyle = async (element: any, expectedStyles: Record) => { - for (const [property, expectedValue] of Object.entries(expectedStyles)) { - const actualValue = await element.evaluate( - (el: any, property: any) => getComputedStyle(el)[property], - property, - ); - expect(actualValue).toBe(expectedValue); - } - }; - - await test.step('Verify trigger margins', async () => { - await checkStyle(datePickerTrigger, { marginTop: '8px' }); - }); - - await test.step('Verify SVG dimensions and paddings', async () => { - const svg = datePickerTrigger.locator('svg'); - await checkStyle(svg, { - paddingLeft: '8px', - paddingRight: '8px', }); - await expect(svg).toHaveAttribute('width', '16'); - await expect(svg).toHaveAttribute('height', '16'); }); - await test.step('Verify trigger separator padding', async () => { - await checkStyle(separator, { paddingRight: '8px' }); - }); + test('Verify Month RangePicker mouse interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.MOUSE, + '@date-picker'], + }, async ({ page }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); - await test.step('Verify disabled date style', async () => { - await datePickerTrigger.click(); + const buttons = page.locator('[data-ui-name="Button"]'); + const input = page.locator('input[data-ui-name="MonthRangePicker.Trigger"]'); - await checkStyle(cells.first(), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }); - }); + await test.step('Navigate months via header buttons', async () => { + await locators.monthRangePickerTrigger(page, 2).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Verify available date style', async () => { - await checkStyle(cells.nth(2), { - color: 'rgb(25, 27, 35)', - backgroundColor: 'rgb(255, 255, 255)', - margin: '4px 0px 0px', - }); - }); + const title1 = await locators.title(page).first().textContent(); + const title2 = await locators.title(page).nth(1).textContent(); - await test.step('Select range and open popper again', async () => { - await cells.nth(10).click(); - await cells.nth(11).click(); - await applyButton.click(); - await datePickerTrigger.click(); - }); - - const selectedCells = page.locator('[data-ui-name="CalendarMonths.Unit"][class*="Selected"]'); + await locators.button(page, 'Previous year').click(); + await expect(locators.title(page).first()).not.toHaveText(title1!); + await expect(locators.title(page).nth(1)).not.toHaveText(title2!); - await test.step('Verify selected date style', async () => { - await checkStyle(selectedCells.nth(0), { - margin: '4px 0px 0px', - width: '60px', - height: '32px', + await locators.button(page, 'Next year').click(); + await expect(locators.title(page).first()).toHaveText(title1!); + await expect(locators.title(page).nth(1)).toHaveText(title2!); }); - }); - - await test.step('Verify style for Apply picker button', async () => { - await checkStyle(applyButton, { - color: 'rgb(255, 255, 255)', - backgroundColor: 'rgb(0, 143, 248)', - }); - }); - }); - function formatAriaLabelToInputValue(ariaLabel: string | null): string { - if (!ariaLabel) { - throw new Error('aria-label is null'); - } - - const parsedDate = new Date(ariaLabel); - - if (isNaN(parsedDate.getTime())) { - throw new Error(`Invalid aria-label date: ${ariaLabel}`); - } - - const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); - const day = parsedDate.getDate().toString().padStart(2, '0'); - const year = parsedDate.getFullYear().toString(); - - return `${month}/${year}`; - } - - test('Verify Month RangePicker mouse interactions', async ({ page }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const datePicker = page.locator('[data-ui-name="MonthRangePicker.Trigger"]'); - const popper = page.locator('[data-ui-name="MonthRangePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="MonthRangePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthRangePicker.Title"]'); - const headNext = page.locator('[data-ui-name="MonthRangePicker.Next"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const input = page.locator('input[data-ui-name="MonthRangePicker.Trigger"]'); - const apply = page.locator('[data-ui-name="MonthRangePicker.Apply"]'); - const reset = page.locator('[data-ui-name="MonthRangePicker.Reset"]'); - const cells = page.locator('[role="gridcell"]'); - - await test.step('Open and close the date picker', async () => { - await datePicker.nth(2).click(); - await expect(popper).toBeVisible(); - - await datePicker.nth(3).click(); - await expect(popper).not.toBeVisible(); - }); + await test.step('Select start and end dates', async () => { + await locators.cells(page, 10).click(); + const label10 = await locators.cells(page, 10).getAttribute('aria-label'); + await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(label10)); - await test.step('Navigate months via header buttons', async () => { - await datePicker.first().click(); - await page.waitForTimeout(300); - - const title1 = await headTitle.first().textContent(); - const title2 = await headTitle.nth(1).textContent(); - - await headPrev.click(); - await expect(headTitle.first()).not.toHaveText(title1!); - await expect(headTitle.nth(1)).not.toHaveText(title2!); - - await headNext.click(); - await expect(headTitle.first()).toHaveText(title1!); - await expect(headTitle.nth(1)).toHaveText(title2!); - }); + await locators.cells(page, 15).click(); + const label15 = await locators.cells(page, 15).getAttribute('aria-label'); + await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(label15)); + }); - await test.step('Select start and end dates', async () => { - await cells.nth(10).click(); - const label10 = await cells.nth(10).getAttribute('aria-label'); - await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(label10)); + await test.step('Reselect start date and reset end', async () => { + await locators.cells(page, 15).click(); + await page.waitForTimeout(300); + const label = await locators.cells(page, 15).getAttribute('aria-label'); - await cells.nth(15).click(); - const label15 = await cells.nth(15).getAttribute('aria-label'); - await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(label15)); - }); + await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(label)); + await expect(input.nth(1)).toHaveValue(''); - await test.step('Reselect start date and reset end', async () => { - await cells.nth(15).click(); - await page.waitForTimeout(300); - const label = await cells.nth(15).getAttribute('aria-label'); + await locators.cells(page, 15).click(); + await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(label)); + }); - await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(label)); - await expect(input.nth(1)).toHaveValue(''); + await test.step('Select new date range', async () => { + await locators.cells(page, 17).click(); + const label17 = await locators.cells(page, 17).getAttribute('aria-label'); + await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(label17)); + await expect(input.nth(1)).toHaveValue(''); - await cells.nth(15).click(); - await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(label)); - }); + await locators.cells(page, 20).click(); + const label20 = await locators.cells(page, 20).getAttribute('aria-label'); + await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(label20)); + }); - await test.step('Select new date range', async () => { - await cells.nth(17).click(); - const label17 = await cells.nth(17).getAttribute('aria-label'); - await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(label17)); - await expect(input.nth(1)).toHaveValue(''); + await test.step('Click outside resets input values', async () => { + await locators.monthRangePickerTrigger(page, 2).click(); + await expect(input.nth(0)).toHaveValue(''); + await expect(input.nth(1)).toHaveValue(''); + }); - await cells.nth(20).click(); - const label20 = await cells.nth(20).getAttribute('aria-label'); - await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(label20)); - }); + await test.step('Apply a selected range', async () => { + await locators.monthRangePickerTrigger(page, 2).click(); + await page.waitForTimeout(200); - await test.step('Click outside resets input values', async () => { - await datePicker.nth(2).click(); - await expect(input.nth(0)).toHaveValue(''); - await expect(input.nth(1)).toHaveValue(''); - }); + await locators.cells(page, 5).click(); + await locators.cells(page, 7).click(); + await locators.button(page, 'Apply').click(); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + }); - await test.step('Apply a selected range', async () => { - await datePicker.nth(2).click(); - await page.waitForTimeout(200); + await test.step('Reset via Reset button', async () => { + await locators.monthRangePickerTrigger(page, 2).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await cells.nth(5).click(); - await cells.nth(7).click(); - await apply.click(); + await locators.button(page, 'Reset').click(); + await expect(input.nth(0)).toHaveValue(''); + await expect(input.nth(1)).toHaveValue(''); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + }); - const startLabel = await cells.nth(5).getAttribute('aria-label'); - const endLabel = await cells.nth(7).getAttribute('aria-label'); - await expect(input.nth(0)).toHaveValue(formatAriaLabelToInputValue(startLabel)); - await expect(input.nth(1)).toHaveValue(formatAriaLabelToInputValue(endLabel)); - }); + await test.step('Quick select today’s range', async () => { + await locators.monthRangePickerTrigger(page, 2).click(); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Reset via Reset button', async () => { - await datePicker.nth(2).click(); - await page.waitForTimeout(200); + await buttons.nth(3).click(); - await reset.click(); - await expect(input.nth(0)).toHaveValue(''); - await expect(input.nth(1)).toHaveValue(''); - await expect(popper).not.toBeVisible(); + await expect(input.nth(0)).not.toHaveValue(''); + await expect(input.nth(1)).not.toHaveValue(''); + }); }); - await test.step('Quick select today’s range', async () => { - await datePicker.nth(2).click(); - await buttons.nth(3).click(); + test('Verify Month RangePicker keyboard interactions', { + tag: [TAG.PRIORITY_HIGH, + TAG.KEYBOARD, + '@date-picker'], + }, async ({ page, browserName }) => { + await loadPage(page, 'stories/components/date-picker/docs/examples/monthrangepicker.tsx', 'en'); + const buttons = page.locator('[data-ui-name="Button"]'); + const input = page.locator('input[data-ui-name="MonthRangePicker.Trigger"]'); - await expect(input.nth(0)).not.toHaveValue(''); - await expect(input.nth(1)).not.toHaveValue(''); - }); - }); + const pressTab = async (times = 1) => { + for (let i = 0; i < times; i++) { + await page.keyboard.press('Tab'); + } + }; - test('Verify Month RangePicker keyboard interactions', async ({ page, browserName }) => { - const standPath = 'stories/components/date-picker/docs/examples/monthrangepicker.tsx'; - const htmlContent = await e2eStandToHtml(standPath, 'en'); - await page.setContent(htmlContent); - - const popper = page.locator('[data-ui-name="MonthRangePicker.Popper"]'); - const headPrev = page.locator('[data-ui-name="MonthRangePicker.Prev"]'); - const headTitle = page.locator('[data-ui-name="MonthRangePicker.Title"]'); - const headNext = page.locator('[data-ui-name="MonthRangePicker.Next"]'); - const buttons = page.locator('[data-ui-name="Button"]'); - const input = page.locator('input[data-ui-name="MonthRangePicker.Trigger"]'); - const apply = page.locator('[data-ui-name="MonthRangePicker.Apply"]'); - const reset = page.locator('[data-ui-name="MonthRangePicker.Reset"]'); - - const pressTab = async (times = 1) => { - for (let i = 0; i < times; i++) { - await page.keyboard.press('Tab'); - } - }; - - await test.step('Open popper using Enter key', async () => { - await pressTab(3); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await expect(popper).toBeFocused(); - }); + await test.step('Open popper using Enter key', async () => { + await pressTab(3); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await test.step('Close popper using Escape key', async () => { - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); - }); + await expect(locators.popper(page)).toBeFocused(); + }); - await test.step('Reopen popper using Space key', async () => { - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await expect(popper).toBeFocused(); - }); + await test.step('Close popper using Escape key', async () => { + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + }); - await test.step('Navigate header controls with keyboard', async () => { - await pressTab(1); // Focus Prev - await expect(headPrev).toBeFocused(); + await test.step('Reopen popper using Space key', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - const [initialFrom, initialTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); + await expect(locators.popper(page)).toBeFocused(); + }); - await page.keyboard.press('Enter'); - await page.waitForTimeout(50); + await test.step('Navigate header controls with keyboard', async () => { + await pressTab(1); // Focus Prev + await expect(locators.button(page, 'Previous year')).toBeFocused(); - const [updatedFrom, updatedTo] = await Promise.all([ - headTitle.first().textContent(), - headTitle.nth(1).textContent(), - ]); + const [initialFrom, initialTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); - expect(updatedFrom).not.toBe(initialFrom); - expect(updatedTo).not.toBe(initialTo); + await page.keyboard.press('Enter'); + await page.waitForTimeout(50); - await pressTab(2); // Focus Next - await expect(headNext).toBeFocused(); + const [updatedFrom, updatedTo] = await Promise.all([ + locators.title(page).first().textContent(), + locators.title(page).nth(1).textContent(), + ]); - await page.keyboard.press('Enter'); - await page.waitForTimeout(50); + expect(updatedFrom).not.toBe(initialFrom); + expect(updatedTo).not.toBe(initialTo); - await expect(headTitle.first()).toHaveText(initialFrom!); - await expect(headTitle.nth(1)).toHaveText(initialTo!); - }); + await pressTab(2); // Focus Next + await expect(locators.button(page, 'Next year')).toBeFocused(); - await test.step('Tab through calendar and action buttons', async () => { - await page.keyboard.press('Shift+Tab'); // Calendar - await expect( - page.locator('[data-ui-name="MonthRangePicker.Calendar"]').first(), - ).toBeFocused(); + await page.keyboard.press('Enter'); + await page.waitForTimeout(50); - await pressTab(2); // period button - await expect(buttons.first()).toBeFocused(); + await expect(locators.title(page).first()).toHaveText(initialFrom!); + await expect(locators.title(page).nth(1)).toHaveText(initialTo!); + }); - await pressTab(4); // Apply - await expect(apply).toBeFocused(); + await test.step('Tab through calendar and action buttons', async () => { + await page.keyboard.press('Shift+Tab'); // Calendar + await expect( + page.locator('[data-ui-name="MonthRangePicker.Calendar"]').first(), + ).toBeFocused(); - await pressTab(1); // Reset - await expect(reset).toBeFocused(); - }); + await pressTab(2); // period button + await expect(buttons.first()).toBeFocused(); - await test.step('Select range using arrow keys and keyboard', async () => { - await page.keyboard.press('Tab'); // Back to grid - - const [initialLeft, initialRight] = await Promise.all([ - input.nth(0).inputValue(), - input.nth(1).inputValue(), - ]); - - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await page.keyboard.press('ArrowLeft'); - await page.keyboard.press('Space'); - await page.waitForTimeout(50); - const [start, middle] = await Promise.all([ - input.nth(0).inputValue(), - input.nth(1).inputValue(), - ]); - - if (browserName !== 'webkit') { - // works unstable on webkit in non debug mode - expect(start).not.toBe(initialLeft); - expect(middle).toBe(initialRight); - } - await page.keyboard.press('Space'); - await page.waitForTimeout(50); - - const [confirmedStart, confirmedEnd] = await Promise.all([ - input.nth(0).inputValue(), - input.nth(1).inputValue(), - ]); - if (browserName !== 'webkit') { - // wprks unstable on webkit in non debug mode - expect(confirmedStart).toBe(start); - expect(confirmedEnd).not.toBe(middle); - } - await page.keyboard.press('Escape'); - await apply.waitFor({ state: 'hidden' }); - - const [resetStart, resetEnd] = await Promise.all([ - input.nth(0).inputValue(), - input.nth(1).inputValue(), - ]); - - expect(resetStart).toBe(initialLeft); - expect(resetEnd).toBe(initialRight); - }); + await pressTab(4); // Apply + await expect(await locators.button(page, 'Apply')).toBeFocused(); - await test.step('Apply range via keyboard interaction', async () => { - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); - await page.keyboard.press('ArrowDown'); - await page.keyboard.press('Space'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('ArrowRight'); - await page.keyboard.press('Space'); + await pressTab(1); // Reset + await expect(locators.button(page, 'Reset')).toBeFocused(); + }); - await pressTab(5); - await expect(apply).toBeFocused(); + await test.step('Select range using arrow keys and keyboard', async () => { + await page.keyboard.press('Tab'); // Back to grid + + const [initialLeft, initialRight] = await Promise.all([ + input.nth(0).inputValue(), + input.nth(1).inputValue(), + ]); + + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await page.keyboard.press('ArrowLeft'); + await page.keyboard.press('Space'); + await page.waitForTimeout(50); + const [start, middle] = await Promise.all([ + input.nth(0).inputValue(), + input.nth(1).inputValue(), + ]); + + if (browserName !== 'webkit') { + // works unstable on webkit in non debug mode + expect(start).not.toBe(initialLeft); + expect(middle).toBe(initialRight); + } + await page.keyboard.press('Space'); + await page.waitForTimeout(50); + + const [confirmedStart, confirmedEnd] = await Promise.all([ + input.nth(0).inputValue(), + input.nth(1).inputValue(), + ]); + if (browserName !== 'webkit') { + // wprks unstable on webkit in non debug mode + expect(confirmedStart).toBe(start); + expect(confirmedEnd).not.toBe(middle); + } + await page.keyboard.press('Escape'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'hidden' }); + const [resetStart, resetEnd] = await Promise.all([ + input.nth(0).inputValue(), + input.nth(1).inputValue(), + ]); - const [left, right] = await Promise.all([ - input.nth(0).inputValue(), - input.nth(1).inputValue(), - ]); + expect(resetStart).toBe(initialLeft); + expect(resetEnd).toBe(initialRight); + }); - expect(left).not.toBe(''); - expect(right).not.toBe(''); - }); + await test.step('Apply range via keyboard interaction', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('Space'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('ArrowRight'); + await page.keyboard.press('Space'); + + await pressTab(5); + await expect(locators.button(page, 'Apply')).toBeFocused(); + + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); + + const [left, right] = await Promise.all([ + input.nth(0).inputValue(), + input.nth(1).inputValue(), + ]); + + expect(left).not.toBe(''); + expect(right).not.toBe(''); + }); - await test.step('Reset range using keyboard', async () => { - await page.keyboard.press('Space'); - await apply.waitFor({ state: 'visible' }); - await expect(popper).toHaveCount(1); + await test.step('Reset range using keyboard', async () => { + await page.keyboard.press('Space'); + await locators.button(page, 'Previous year').waitFor({ state: 'visible' }); - await pressTab(9); // Focus Reset - await expect(reset).toBeFocused(); + await pressTab(9); // Focus Reset + await expect(locators.button(page, 'Reset')).toBeFocused(); - await page.keyboard.press('Enter'); - await apply.waitFor({ state: 'hidden' }); - await expect(popper).toHaveCount(0); + await page.keyboard.press('Enter'); + await locators.button(page, 'Previous year').waitFor({ state: 'hidden' }); - const [left, right] = await Promise.all([ - input.nth(0).inputValue(), - input.nth(1).inputValue(), - ]); + const [left, right] = await Promise.all([ + input.nth(0).inputValue(), + input.nth(1).inputValue(), + ]); - expect(left).toBe(''); - expect(right).toBe(''); + expect(left).toBe(''); + expect(right).toBe(''); + }); }); }); }); diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png new file mode 100644 index 0000000000..b401324ba1 Binary files /dev/null and b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png new file mode 100644 index 0000000000..43d243e3a0 Binary files /dev/null and b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png differ diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-states-and-props-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-firefox-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-webkit-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-1-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-firefox-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-webkit-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-2-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-firefox-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-webkit-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-3-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-chromium-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-chromium-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-chromium-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-firefox-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-firefox-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-firefox-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-firefox-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-webkit-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-webkit-linux.png similarity index 100% rename from semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-webkit-linux.png rename to semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/-visual-Month-Range-Trigger-Verify-trigger-when-entering-date-manually-4-webkit-linux.png diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png deleted file mode 100644 index a720571a9b..0000000000 Binary files a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-1-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png b/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png deleted file mode 100644 index a7bc6c79a8..0000000000 Binary files a/semcore/date-picker/__tests__/month-range-picker.browser-test.tsx-snapshots/Month-Range-Trigger-Verify-trigger-states-and-props-2-chromium-linux.png and /dev/null differ diff --git a/semcore/date-picker/__tests__/utils.ts b/semcore/date-picker/__tests__/utils.ts index bd59f3c036..04b34f3e39 100644 --- a/semcore/date-picker/__tests__/utils.ts +++ b/semcore/date-picker/__tests__/utils.ts @@ -1,4 +1,5 @@ export const RealDate = global.Date; +import { expect, test } from '@semcore/testing-utils/playwright'; // https://github.com/facebook/jest/issues/2234#issuecomment-384884729 export function mockDate(isoDate: any) { @@ -16,3 +17,37 @@ export function mockDate(isoDate: any) { } }; } + +export function formatAriaLabelToInputValue(ariaLabel: string | null): string { + if (!ariaLabel) { + throw new Error('aria-label is null'); + } + + let parsedDate = new Date(ariaLabel); + let hasDay = true; + + if (isNaN(parsedDate.getTime())) { + parsedDate = new Date(`${ariaLabel} 1`); + hasDay = false; + } + + if (isNaN(parsedDate.getTime())) { + throw new Error(`Invalid aria-label date: ${ariaLabel}`); + } + + const month = (parsedDate.getMonth() + 1).toString().padStart(2, '0'); + const day = parsedDate.getDate().toString().padStart(2, '0'); + const year = parsedDate.getFullYear().toString(); + + return hasDay ? `${month}/${day}/${year}` : `${month}/${year}`; +} + +export const checkStyle = async (element: any, expectedStyles: Record) => { + for (const [property, expectedValue] of Object.entries(expectedStyles)) { + const actualValue = await element.evaluate( + (el: any, property: any) => getComputedStyle(el)[property], + property, + ); + expect(actualValue).toBe(expectedValue); + } +}; diff --git a/semcore/date-picker/src/components/DateRangeComparatorAbstract.jsx b/semcore/date-picker/src/components/DateRangeComparatorAbstract.jsx index 5f7aad33aa..cc0699cdb4 100644 --- a/semcore/date-picker/src/components/DateRangeComparatorAbstract.jsx +++ b/semcore/date-picker/src/components/DateRangeComparatorAbstract.jsx @@ -66,7 +66,12 @@ class DateRangeComparatorAbstract extends Component { return dayjs(date).subtract(amount, unit).toDate(); }; + prevButtonRef = React.createRef(); + nextButtonRef = React.createRef(); popperRef = React.createRef(); + resetButtonRef = React.createRef(); + applyButtonRef = React.createRef(); + periodRefs = []; unitRefs = {}; getPeriodProps() { @@ -100,6 +105,11 @@ class DateRangeComparatorAbstract extends Component { onDisplayedPeriodChange, 'role': 'listbox', 'aria-label': getI18nText('periods'), + 'periodRef': (index) => (element) => { + if (!element) return; + + this.periodRefs[index] = element; + }, }; } @@ -117,6 +127,7 @@ class DateRangeComparatorAbstract extends Component { const { navigateStep } = this; return { getI18nText, + 'ref': this.prevButtonRef, 'onClick': this.bindHandlerNavigateClick(-1), 'aria-label': navigateStep === 'month' ? getI18nText('prevMonth') : getI18nText('prevYear'), }; @@ -127,6 +138,7 @@ class DateRangeComparatorAbstract extends Component { const { navigateStep } = this; return { getI18nText, + 'ref': this.nextButtonRef, 'onClick': this.bindHandlerNavigateClick(1), 'aria-label': navigateStep === 'month' ? getI18nText('nextMonth') : getI18nText('nextYear'), }; @@ -188,6 +200,7 @@ class DateRangeComparatorAbstract extends Component { return { getI18nText, onClick: this.handleApplyClick, + ref: this.applyButtonRef, }; } @@ -196,6 +209,7 @@ class DateRangeComparatorAbstract extends Component { return { getI18nText, onClick: () => this.handleApply(null, null), + ref: this.resetButtonRef, }; } @@ -212,10 +226,12 @@ class DateRangeComparatorAbstract extends Component { handleKeydownDown = (place) => (e) => { const { displayedPeriod, preselectedValue, visible, focusedRange } = this.asProps; - const key = e.key; + const { key, target } = e; const highlighted = focusedRange === 'compare' ? this.asProps.compareHighlighted : this.asProps.highlighted; + if ([' ', 'Enter'].includes(key) && [this.prevButtonRef.current, this.nextButtonRef.current].includes(target)) return; + if (place === 'trigger' && INTERACTION_KEYS.includes(key)) { e.preventDefault(); e.stopPropagation(); @@ -254,7 +270,16 @@ class DateRangeComparatorAbstract extends Component { return displayedPeriod; }; - if (place === 'popper' && e.key === ' ' && highlighted.length) { + const isPeriodTarget = this.periodRefs.find((el) => el === target); + const isResetButtonTarget = target === this.resetButtonRef.current; + const isApplyButtonTarget = target === this.applyButtonRef.current; + const areTargetedControls = isPeriodTarget || isResetButtonTarget || isApplyButtonTarget; + + if (place === 'popper' && + e.key === ' ' && + highlighted.length && + !areTargetedControls + ) { const highlightedDate = highlighted[1] || highlighted[0]; if (!this.isDisabled(highlightedDate)) { diff --git a/semcore/date-picker/src/components/PickerAbstract.jsx b/semcore/date-picker/src/components/PickerAbstract.jsx index b1eea8de34..946efaccc1 100644 --- a/semcore/date-picker/src/components/PickerAbstract.jsx +++ b/semcore/date-picker/src/components/PickerAbstract.jsx @@ -40,6 +40,8 @@ class PickerAbstract extends Component { return dayjs(date).subtract(amount, unit).toDate(); }; + prevButtonRef = React.createRef(); + nextButtonRef = React.createRef(); popperRef = React.createRef(); unitRefs = {}; @@ -95,7 +97,9 @@ class PickerAbstract extends Component { handlerKeyDown = (place) => (e) => { const { value, displayedPeriod, highlighted, disabled: _disabled, visible } = this.asProps; - const key = e.key; + const { key, target } = e; + + if ([' ', 'Enter'].includes(key) && [this.prevButtonRef.current, this.nextButtonRef.current].includes(target)) return; if (place === 'trigger' && INTERACTION_KEYS.includes(key)) { e.stopPropagation(); @@ -116,7 +120,7 @@ class PickerAbstract extends Component { return day.toDate(); }; - if (place === 'popper' && (e.key === ' ' || (e.key === 'Enter' && highlighted.length))) { + if (place === 'popper' && (e.key === ' ' || e.key === 'Enter') && highlighted.length) { if (!this.isDisabled(highlighted[0])) { this.handlers.value(highlighted[0]); } @@ -197,6 +201,7 @@ class PickerAbstract extends Component { const { navigateStep } = this; return { + 'ref': this.nextButtonRef, 'onClick': this.bindHandlerNavigateClick(1), getI18nText, 'aria-label': navigateStep === 'month' ? getI18nText('nextMonth') : getI18nText('nextYear'), @@ -208,6 +213,7 @@ class PickerAbstract extends Component { const { navigateStep } = this; return { + 'ref': this.prevButtonRef, 'onClick': this.bindHandlerNavigateClick(-1), getI18nText, 'aria-label': navigateStep === 'month' ? getI18nText('prevMonth') : getI18nText('prevYear'), diff --git a/semcore/date-picker/src/components/RangePickerAbstract.jsx b/semcore/date-picker/src/components/RangePickerAbstract.jsx index 473cd70737..e2d794e3ae 100644 --- a/semcore/date-picker/src/components/RangePickerAbstract.jsx +++ b/semcore/date-picker/src/components/RangePickerAbstract.jsx @@ -52,7 +52,12 @@ class RangePickerAbstract extends Component { return dayjs(date).subtract(amount, unit).toDate(); }; + applyButtonRef = React.createRef(); + resetButtonRef = React.createRef(); + prevButtonRef = React.createRef(); + nextButtonRef = React.createRef(); popperRef = React.createRef(); + periodRefs = []; unitRefs = {}; navigateStep; @@ -109,7 +114,9 @@ class RangePickerAbstract extends Component { handlerKeyDown = (place) => (e) => { const { displayedPeriod, highlighted, preselectedValue, visible } = this.asProps; - const key = e.key; + const { key, target } = e; + + if ([' ', 'Enter'].includes(key) && [this.prevButtonRef.current, this.nextButtonRef.current].includes(target)) return; if (place === 'trigger' && INTERACTION_KEYS.includes(key)) { e.stopPropagation(); @@ -151,7 +158,17 @@ class RangePickerAbstract extends Component { if (place === 'popper' && e.key === 'Enter' && (e.metaKey || e.ctrlKey)) { return this.handleApplyClick(); } - if (place === 'popper' && e.key === ' ' && highlighted.length) { + + const isPeriodTarget = this.periodRefs.find((el) => el === target); + const isResetButtonTarget = target === this.resetButtonRef.current; + const isApplyButtonTarget = target === this.applyButtonRef.current; + const areTargetedControls = isPeriodTarget || isResetButtonTarget || isApplyButtonTarget; + + if (place === 'popper' && + e.key === ' ' && + highlighted.length && + !areTargetedControls + ) { const highlightedDate = highlighted[1] || highlighted[0]; if (!this.isDisabled(highlightedDate)) { @@ -331,6 +348,7 @@ class RangePickerAbstract extends Component { const { navigateStep } = this; return { + 'ref': this.nextButtonRef, 'onClick': this.bindHandlerNavigateClick(1), getI18nText, 'aria-label': navigateStep === 'month' ? getI18nText('nextMonth') : getI18nText('nextYear'), @@ -342,6 +360,7 @@ class RangePickerAbstract extends Component { const { navigateStep } = this; return { + 'ref': this.prevButtonRef, 'onClick': this.bindHandlerNavigateClick(-1), getI18nText, 'aria-label': navigateStep === 'month' ? getI18nText('prevMonth') : getI18nText('prevYear'), @@ -397,6 +416,11 @@ class RangePickerAbstract extends Component { onDisplayedPeriodChange, 'role': 'listbox', 'aria-label': getI18nText('periods'), + 'periodRef': (index) => (element) => { + if (!element) return; + + this.periodRefs[index] = element; + }, }; } @@ -410,6 +434,7 @@ class RangePickerAbstract extends Component { return { getI18nText, onClick: this.handleApplyClick, + ref: this.applyButtonRef, }; } @@ -418,6 +443,7 @@ class RangePickerAbstract extends Component { return { getI18nText, onClick: () => this.handleApply([]), + ref: this.resetButtonRef, }; } diff --git a/semcore/date-picker/src/components/index.jsx b/semcore/date-picker/src/components/index.jsx index 30a17b2caf..1d046a58b6 100644 --- a/semcore/date-picker/src/components/index.jsx +++ b/semcore/date-picker/src/components/index.jsx @@ -101,13 +101,14 @@ export class Period extends Component { render() { const SPeriod = Root; - const { styles, value, onChange, periods, onHighlightedChange, onDisplayedPeriodChange } = + const { styles, value, onChange, periods, onHighlightedChange, onDisplayedPeriodChange, periodRef } = this.asProps; return sstyled(styles)( {periods.map(({ value: period, onClick, onMouseEnter, onMouseLeave, ...other }, i) => (