Skip to content

Commit

Permalink
Tests on fixed header
Browse files Browse the repository at this point in the history
  • Loading branch information
DaryaLari committed Nov 29, 2024
1 parent 2080de1 commit 4d117be
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 8 deletions.
2 changes: 2 additions & 0 deletions src/i18n-keysets/dash.main.view/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
"label_updating": "Updating",
"toast_paste-invalid-workbook-entry": "Pasting widgets linked to objects from another workbook is forbidden",
"toast_unsaved": "There are unsaved changes on the page. Are you sure?",
"tooltip_collapse-fixed-group": "Collapse pinned group",
"tooltip_expand-fixed-group": "Expand pinned group",
"warning_paste-invalid-workbook-entry": "To work with this object within another workbook, please migrate all linked objects from the source workbook. <link>Migrating objects to workbooks</link>"
}
2 changes: 2 additions & 0 deletions src/i18n-keysets/dash.main.view/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
"label_updating": "Обновление",
"toast_paste-invalid-workbook-entry": "Не допускается вставка виджетов, у которых есть связи с объектами из другого воркбука",
"toast_unsaved": "На странице есть несохраненные изменения. Вы уверены?",
"tooltip_collapse-fixed-group": "Свернуть закрепленную группу",
"tooltip_expand-fixed-group": "Развернуть закрепленную группу",
"warning_paste-invalid-workbook-entry": "Чтобы работать с объектом в рамках другого воркбука, пожалуйста, перенесите в этот воркбук все связанные объекты из исходного воркбука. <link>Миграция объектов в воркбук</link>"
}
8 changes: 8 additions & 0 deletions src/shared/constants/qa/dash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ export enum DashCommonQa {
RelationsRowPopover = 'dialog-relations-row-popover',
}

export enum FixedHeaderQa {
ExpandCollapseFixedHeaderButton = 'expand-collapse-fixed-header-button',
StaticFixedHeaderGroupWrapper = 'static-fixed-header-group-wrapper',
StaticFixedHeaderGroupContent = 'static-fixed-header-group-content',
HidableFixedHeaderGroupWrapper = 'hidable-fixed-header-group-wrapper',
HidableFixedHeaderGroupContent = 'hidable-fixed-header-group-content',
}

export enum DashRelationTypes {
output = 'relation-type-option-output',
input = 'relation-type-option-input',
Expand Down
6 changes: 6 additions & 0 deletions src/ui/units/dash/containers/Body/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
DashKitOverlayMenuQa,
DashTabItemType,
Feature,
FixedHeaderQa,
LOADED_DASH_CLASS,
UPDATE_STATE_DEBOUNCE_TIME,
} from 'shared';
Expand Down Expand Up @@ -635,6 +636,11 @@ class Body extends React.PureComponent<BodyProps> {
size="xl"
width="max"
pin="brick-round"
title={i18n(
'dash.main.view',
isCollapsed ? 'tooltip_expand-fixed-group' : 'tooltip_collapse-fixed-group',
)}
qa={FixedHeaderQa.ExpandCollapseFixedHeaderButton}
>
<Icon data={isCollapsed ? ArrowChevronDown : ArrowChevronUp} />
</Button>
Expand Down
10 changes: 4 additions & 6 deletions src/ui/units/dash/containers/FixedHeader/FixedHeader.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,15 @@ $fixedSectionOffset: 8px;

&_edit-mode {
border-bottom: 1px solid var(--g-color-line-generic);
padding-bottom: $fixedSectionOffset;
}
}

&__container-wrapper {
display: flex;
padding-bottom: $fixedSectionOffset;
flex-direction: row;
flex: 1;
position: relative;

@include flexReactGridLayout;
}
Expand All @@ -89,6 +90,7 @@ $fixedSectionOffset: 8px;
display: flex;
flex-direction: row;
min-height: 52px;
padding-bottom: $fixedSectionOffset;

@include dndHighlight;

Expand All @@ -112,6 +114,7 @@ $fixedSectionOffset: 8px;
overflow: clip;
min-height: 0;
max-height: 0;
padding: 0;
}
}

Expand All @@ -124,10 +127,5 @@ $fixedSectionOffset: 8px;
pointer-events: none;
color: var(--g-color-text-hint);
text-align: center;

&.with-offset {
top: calc(50% - #{$fixedSectionOffset});
transform: translateY(calc(-1 * calc(50% - calc(#{$fixedSectionOffset}) / 2)));
}
}
}
15 changes: 13 additions & 2 deletions src/ui/units/dash/containers/FixedHeader/FixedHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import {useBodyScrollLock, useForkRef} from '@gravity-ui/uikit';
import block from 'bem-cn-lite';
import {I18n} from 'i18n';
import {FixedHeaderQa} from 'shared';

import './FixedHeader.scss';

Expand Down Expand Up @@ -125,13 +126,17 @@ export const FixedHeaderControls: React.FC<FixedHeaderControlsProps> = (props) =
return (
<div ref={placeholderRef} className={b('controls-placeholder', {hidden: !content})}>
<div
data-qa={FixedHeaderQa.StaticFixedHeaderGroupWrapper}
style={style}
className={b('controls', {
fixed: isFixed && !editMode,
'edit-mode': editMode,
})}
>
<div className={b('controls-grid')}>
<div
className={b('controls-grid')}
data-qa={FixedHeaderQa.StaticFixedHeaderGroupContent}
>
{content}
<div className={b('controls-settings')}>{props.controls}</div>
</div>
Expand Down Expand Up @@ -204,6 +209,7 @@ export const FixedHeaderContainer: React.FC<FixedHeaderContainerProps> = (props)
style={{height: containerHeight}}
>
<div
data-qa={FixedHeaderQa.HidableFixedHeaderGroupWrapper}
ref={containerRef}
style={style}
className={b('container', {
Expand All @@ -212,7 +218,12 @@ export const FixedHeaderContainer: React.FC<FixedHeaderContainerProps> = (props)
'edit-mode': editMode,
})}
>
<div className={b('container-wrapper')}>{content}</div>
<div
data-qa={FixedHeaderQa.HidableFixedHeaderGroupContent}
className={b('container-wrapper', {'edit-mode': editMode})}
>
{content}
</div>
</div>
</div>
);
Expand Down
157 changes: 157 additions & 0 deletions tests/opensource-suites/dash/base/fixedHeader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import {Page, expect} from '@playwright/test';

import DashboardPage from '../../../page-objects/dashboard/DashboardPage';
import {openTestPage, slct} from '../../../utils';
import datalensTest from '../../../utils/playwright/globalTestDefinition';
import {ActionPanelQA} from '../../../../src/shared';

const dashboardKey = 'at6wshbewj36x-fixed-header-tests';
const tabsIds = {
twoGroups: 'X5',
onlySecondGroup: 'Ja',
overflownSecondGroup: 'vJ',
};

function getTabUrl(tabName: string) {
return `/${dashboardKey}?tab=${tabName}`;
}

datalensTest.describe('Fixed header', () => {
datalensTest('Header with 2 groups', async ({page}: {page: Page}) => {
await openTestPage(page, getTabUrl(tabsIds.twoGroups));
const dashboardPage = new DashboardPage({page});
const fixedHeader = dashboardPage.fixedHeader;
const actionPanelHeight =
(await dashboardPage.page.locator(slct(ActionPanelQA.ActionPanel)).boundingBox())
?.height ?? 0;

const collapsibleStateToggleButton = fixedHeader.expandCollapseButton;

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeVisible();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeVisible();

const initialStaticFixedHeaderGroupVerticalOffset =
await fixedHeader.getStaticFixedHeaderGroupVerticalOffset();

// check that "fixed" header is not fixed without scrolling
expect(initialStaticFixedHeaderGroupVerticalOffset).toBeGreaterThan(actionPanelHeight);
expect(await fixedHeader.getHidableFixedHeaderGroupVerticalOffset()).toBeGreaterThan(
initialStaticFixedHeaderGroupVerticalOffset + actionPanelHeight,
);

await fixedHeader.toggleFixedHeaderCollapsibleState(); // collapse

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeVisible();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeHidden();

await page.mouse.wheel(0, 500);

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeVisible();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeHidden();

expect(await fixedHeader.getStaticFixedHeaderGroupVerticalOffset()).toEqual(
actionPanelHeight,
);

await fixedHeader.toggleFixedHeaderCollapsibleState(); // expand

await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeVisible();

const staticFixedHeaderHeight =
(await fixedHeader.staticFixedHeaderGroupWrapper.boundingBox())?.height ?? 0;
expect(await fixedHeader.getHidableFixedHeaderGroupVerticalOffset()).toEqual(
actionPanelHeight + staticFixedHeaderHeight,
);
});

datalensTest('With second group only', async ({page}: {page: Page}) => {
await openTestPage(page, getTabUrl(tabsIds.onlySecondGroup));
const dashboardPage = new DashboardPage({page});
const fixedHeader = dashboardPage.fixedHeader;
const actionPanelHeight =
(await dashboardPage.page.locator(slct(ActionPanelQA.ActionPanel)).boundingBox())
?.height ?? 0;

const collapsibleStateToggleButton = fixedHeader.expandCollapseButton;

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeHidden();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeVisible();

const initialStaticHidableHeaderGroupVerticalOffset =
await fixedHeader.getHidableFixedHeaderGroupVerticalOffset();

// check that "fixed" header is not fixed without scrolling
expect(initialStaticHidableHeaderGroupVerticalOffset).toBeGreaterThan(actionPanelHeight);

await fixedHeader.toggleFixedHeaderCollapsibleState(); // collapse

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeHidden();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeHidden();

await page.mouse.wheel(0, 500);

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeHidden();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeHidden();

await fixedHeader.toggleFixedHeaderCollapsibleState(); // expand

await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeVisible();

expect(await fixedHeader.getHidableFixedHeaderGroupVerticalOffset()).toEqual(
actionPanelHeight,
);
});
datalensTest('Header with overflown second group', async ({page}: {page: Page}) => {
await openTestPage(page, getTabUrl(tabsIds.overflownSecondGroup));
const dashboardPage = new DashboardPage({page});
const fixedHeader = dashboardPage.fixedHeader;
const actionPanelHeight =
(await dashboardPage.page.locator(slct(ActionPanelQA.ActionPanel)).boundingBox())
?.height ?? 0;

const collapsibleStateToggleButton = fixedHeader.expandCollapseButton;

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeVisible();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeVisible();

const body = page.locator('body');

const initialStaticFixedHeaderGroupVerticalOffset =
await fixedHeader.getStaticFixedHeaderGroupVerticalOffset();

// check that "fixed" header is not fixed without scrolling
expect(initialStaticFixedHeaderGroupVerticalOffset).toBeGreaterThan(actionPanelHeight);
expect(await fixedHeader.getHidableFixedHeaderGroupVerticalOffset()).toBeGreaterThan(
initialStaticFixedHeaderGroupVerticalOffset + actionPanelHeight,
);

await page.mouse.wheel(0, 500);

const bodyScrollPositionBeforeCollapsing = (await body.boundingBox())?.y ?? 0;
const fixedHeaderScrollPositionBeforeCollapsing =
(await fixedHeader.hidableFixedHeaderGroupWrapper.boundingBox())?.y ?? 0;

await page.mouse.wheel(0, 500);

expect((await body.boundingBox())?.y).toEqual(bodyScrollPositionBeforeCollapsing);
expect((await fixedHeader.hidableFixedHeaderGroupWrapper.boundingBox())?.y).toEqual(
fixedHeaderScrollPositionBeforeCollapsing + 500,
);

await fixedHeader.toggleFixedHeaderCollapsibleState(); // collapse

await expect(collapsibleStateToggleButton).toBeVisible();
await expect(fixedHeader.staticFixedHeaderGroupContent).toBeVisible();
await expect(fixedHeader.hidableFixedHeaderGroupContent).toBeHidden();

await page.mouse.wheel(0, 500);
expect((await body.boundingBox())?.y).toEqual(bodyScrollPositionBeforeCollapsing + 500);
});
});
3 changes: 3 additions & 0 deletions tests/page-objects/dashboard/DashboardPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {CommonUrls} from '../constants/common-urls';
import {EditEntityButton} from '../workbook/EditEntityButton';
import ControlActions from './ControlActions';
import {getUrlStateParam} from '../../suites/dash/helpers';
import {FixedHeader} from './FixedHeader';

export const BUTTON_CHECK_TIMEOUT = 3000;
export const RENDER_TIMEOUT = 4000;
Expand Down Expand Up @@ -112,6 +113,7 @@ class DashboardPage extends BasePage {
dialogCreateEntry: DialogCreateEntry;
editEntityButton: EditEntityButton;
controlActions: ControlActions;
fixedHeader: FixedHeader;

constructor({page}: DashboardPageProps) {
super({page});
Expand All @@ -123,6 +125,7 @@ class DashboardPage extends BasePage {
this.dialogCreateEntry = new DialogCreateEntry(page);
this.editEntityButton = new EditEntityButton(page);
this.controlActions = new ControlActions(page);
this.fixedHeader = new FixedHeader(page);
}

async waitForResponses(url: string, timeout = API_TIMEOUT): Promise<Array<Response>> {
Expand Down
63 changes: 63 additions & 0 deletions tests/page-objects/dashboard/FixedHeader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {Page} from '@playwright/test';
import {slct} from '../../utils';
import {FixedHeaderQa} from '../../../src/shared';

export class FixedHeader {
static selectors = {
expandCollapseButton: slct(FixedHeaderQa.ExpandCollapseFixedHeaderButton),
staticFixedHeaderGroupWrapper: slct(FixedHeaderQa.StaticFixedHeaderGroupWrapper),
staticFixedHeaderGroupContent: slct(FixedHeaderQa.StaticFixedHeaderGroupContent),
hidableFixedHeaderGroupWrapper: slct(FixedHeaderQa.HidableFixedHeaderGroupWrapper),
hidableFixedHeaderGroupContent: slct(FixedHeaderQa.HidableFixedHeaderGroupContent),
};

protected page: Page;

constructor(page: Page) {
this.page = page;
}

get expandCollapseButton() {
return this.page.locator(FixedHeader.selectors.expandCollapseButton);
}

toggleFixedHeaderCollapsibleState() {
return this.page.locator(FixedHeader.selectors.expandCollapseButton).click();
}

get staticFixedHeaderGroupContent() {
return this.page.locator(FixedHeader.selectors.staticFixedHeaderGroupContent);
}

get hidableFixedHeaderGroupContent() {
return this.page.locator(FixedHeader.selectors.hidableFixedHeaderGroupContent);
}

get staticFixedHeaderGroupWrapper() {
return this.page.locator(FixedHeader.selectors.staticFixedHeaderGroupWrapper);
}

get hidableFixedHeaderGroupWrapper() {
return this.page.locator(FixedHeader.selectors.hidableFixedHeaderGroupWrapper);
}

async getStaticFixedHeaderGroupVerticalOffset() {
return (
(
await this.page
.locator(FixedHeader.selectors.staticFixedHeaderGroupWrapper)
.boundingBox()
)?.y ?? 0
);
}

async getHidableFixedHeaderGroupVerticalOffset() {
return (
(
await this.page
.locator(FixedHeader.selectors.hidableFixedHeaderGroupWrapper)
.boundingBox()
)?.y ?? 0
);
}
}

0 comments on commit 4d117be

Please sign in to comment.