Skip to content

Commit 62eb7e0

Browse files
authored
fix(ObjectPage): fix selection & header scroll behavior (#6663)
Fixes #6600 Fixes #6648
1 parent 101e261 commit 62eb7e0

File tree

3 files changed

+256
-49
lines changed

3 files changed

+256
-49
lines changed

packages/main/src/components/ObjectPage/ObjectPage.cy.tsx

Lines changed: 199 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@ import '@ui5/webcomponents-icons/dist/AllIcons.js';
22
import '@ui5/webcomponents-fiori/dist/illustrations/NoData.js';
33
import BarDesign from '@ui5/webcomponents/dist/types/BarDesign.js';
44
import ButtonDesign from '@ui5/webcomponents/dist/types/ButtonDesign.js';
5+
import InputType from '@ui5/webcomponents/dist/types/InputType.js';
56
import TitleLevel from '@ui5/webcomponents/dist/types/TitleLevel.js';
67
import ValueState from '@ui5/webcomponents-base/dist/types/ValueState.js';
78
import IllustrationMessageType from '@ui5/webcomponents-fiori/dist/types/IllustrationMessageType.js';
89
import type { CSSProperties } from 'react';
910
import { useEffect, useReducer, useRef, useState } from 'react';
1011
import type { ObjectPagePropTypes } from '../..';
1112
import {
13+
CheckBox,
14+
Form,
15+
FormGroup,
16+
FormItem,
17+
Input,
18+
Option,
19+
Select,
20+
TextArea,
1221
Avatar,
1322
Bar,
1423
Breadcrumbs,
@@ -38,6 +47,78 @@ import {
3847
import { cypressPassThroughTestsFactory } from '@/cypress/support/utils';
3948

4049
describe('ObjectPage', () => {
50+
it('dynamic children selection', () => {
51+
const TestComp = () => {
52+
const [state, setState] = useState<boolean>(false);
53+
const [sections, add] = useReducer(
54+
(prev) => [
55+
...prev,
56+
<ObjectPageSection key={prev.length + 1} id={`${prev.length + 1}`} titleText={`Section ${prev.length + 1}`}>
57+
<div style={{ height: `${(prev.length + 1) * 50}px` }}>Content {prev.length + 1}</div>
58+
</ObjectPageSection>
59+
],
60+
[]
61+
);
62+
return (
63+
<>
64+
<button onClick={add}>Add</button>
65+
<ObjectPage
66+
data-testid="op"
67+
style={{ height: '800px', scrollBehavior: 'auto' }}
68+
titleArea={DPTitle}
69+
headerArea={DPContent}
70+
onSelectedSectionChange={() => {
71+
setState(!state);
72+
}}
73+
>
74+
{OPContent}
75+
{sections}
76+
</ObjectPage>
77+
</>
78+
);
79+
};
80+
81+
cy.mount(<TestComp />);
82+
83+
cy.wait(100);
84+
cy.get('[ui5-tabcontainer]').findUi5TabByText('Employment').realClick();
85+
cy.findByText('Job Information').should('be.visible');
86+
87+
// add 15 sections
88+
for (let i = 0; i < 15; i++) {
89+
cy.findByText('Add').click();
90+
}
91+
92+
//TabContainer overflow btn
93+
cy.get('[data-ui5-stable="overflow-end"]').realClick();
94+
cy.get('[ui5-list]').should('be.visible');
95+
cy.wait(500);
96+
// select "Section 15"
97+
cy.realPress('PageDown');
98+
cy.wait(500);
99+
cy.realPress('Enter');
100+
cy.get('[ui5-list]').should('not.be.visible');
101+
102+
cy.findByText('Content 15').should('be.visible');
103+
cy.wait(100);
104+
cy.get('[ui5-tabcontainer]').findUi5TabByText('Section 15').should('have.attr', 'aria-selected', 'true');
105+
106+
cy.findByTestId('op').scrollTo(0, 4660);
107+
108+
cy.findByText('Content 7').should('be.visible');
109+
cy.get('[ui5-tabcontainer]').findUi5TabByText('Section 7').should('have.attr', 'aria-selected', 'true');
110+
111+
cy.mount(<TestComp />);
112+
// add 15 sections
113+
for (let i = 0; i < 15; i++) {
114+
cy.findByText('Add').click();
115+
}
116+
cy.findByTestId('op').scrollTo(0, 4660);
117+
118+
cy.findByText('Content 7').should('be.visible');
119+
cy.get('[ui5-tabcontainer]').findUi5TabByText('Section 7').should('have.attr', 'aria-selected', 'true');
120+
});
121+
41122
it('toggle header', () => {
42123
const toggle = cy.spy().as('toggleSpy');
43124
cy.mount(
@@ -278,12 +359,9 @@ describe('ObjectPage', () => {
278359

279360
cy.get('[ui5-tabcontainer]').findUi5TabByText('Employment').focus();
280361
cy.realPress('ArrowDown');
281-
cy.wait(500);
282362
cy.realPress('ArrowDown');
283363
cy.realPress('ArrowDown');
284364
cy.realPress('Enter');
285-
cy.wait(200);
286-
cy.realPress('Enter');
287365
cy.findByText('Job Relationship').should('be.visible');
288366

289367
cy.mount(
@@ -324,6 +402,8 @@ describe('ObjectPage', () => {
324402
cy.realPress('ArrowDown');
325403
cy.realPress('ArrowDown');
326404
cy.realPress('Enter');
405+
// wait for scroll
406+
cy.wait(200);
327407
cy.findByText('Job Relationship').should('be.visible');
328408

329409
cy.findByTestId('footer').should('be.visible');
@@ -353,10 +433,12 @@ describe('ObjectPage', () => {
353433
cy.findByTestId('section 1').should('be.visible');
354434

355435
cy.get('[ui5-tabcontainer]').findUi5TabOpenPopoverButtonByText('Employment').click();
356-
cy.wait(500);
436+
cy.get('[ui5-list]').should('be.visible');
437+
cy.wait(200);
357438
cy.realPress('ArrowDown');
358439
cy.realPress('ArrowDown');
359440
cy.realPress('Enter');
441+
cy.wait(500);
360442
cy.findByText('Job Relationship').should('be.visible');
361443
cy.findByText('Job Information').should('not.be.visible');
362444

@@ -923,6 +1005,57 @@ describe('ObjectPage', () => {
9231005
cy.get('@cb').should('not.been.called');
9241006
});
9251007

1008+
it('onSelectedSectionChange: React state update', () => {
1009+
const TestComp = () => {
1010+
const [state, setState] = useState(false);
1011+
return (
1012+
<ObjectPage
1013+
// increase test speed by setting scroll behavior to instant
1014+
style={{ height: '800px', scrollBehavior: 'auto' }}
1015+
onSelectedSectionChange={() => {
1016+
setState(!state);
1017+
}}
1018+
>
1019+
<ObjectPageSection id={'test1'} titleText={'test1'}>
1020+
<div style={{ height: '900px' }}>
1021+
<div style={{ height: '30%' }}>Content1</div>
1022+
</div>
1023+
</ObjectPageSection>
1024+
<ObjectPageSection id={'test2'} titleText={'test2'}>
1025+
<div style={{ height: '900px' }}>
1026+
<div style={{ height: '30%' }}>Content2</div>
1027+
</div>
1028+
</ObjectPageSection>
1029+
</ObjectPage>
1030+
);
1031+
};
1032+
1033+
cy.mount(<TestComp />);
1034+
cy.get('[ui5-tabcontainer]').findUi5TabByText('test2').realClick();
1035+
cy.findByText('Content1').should('not.be.visible');
1036+
cy.findByText('Content2').should('be.visible');
1037+
cy.get('[ui5-tabcontainer]').findUi5TabByText('test2').should('have.attr', 'aria-selected', 'true');
1038+
cy.get('[ui5-tabcontainer]').findUi5TabByText('test1').should('have.attr', 'aria-selected', 'false');
1039+
});
1040+
1041+
it('header spacer', () => {
1042+
const TestComp = () => {
1043+
return (
1044+
<ObjectPage data-testid="op" style={{ height: '95vh' }} titleArea={DPTitle} headerArea={HeaderWithLargeForm}>
1045+
<ObjectPageSection id="first" titleText="First">
1046+
<div>First Content</div>
1047+
</ObjectPageSection>
1048+
{OPContent}
1049+
</ObjectPage>
1050+
);
1051+
};
1052+
cy.mount(<TestComp />);
1053+
cy.findByTestId('op').scrollTo(0, 649);
1054+
1055+
cy.wait(500);
1056+
cy.findByText('First Content').should('be.visible');
1057+
});
1058+
9261059
cypressPassThroughTestsFactory(ObjectPage);
9271060
});
9281061

@@ -1011,6 +1144,68 @@ const OPContent = [
10111144
</ObjectPageSection>
10121145
];
10131146

1147+
const HeaderWithLargeForm = (
1148+
<ObjectPageHeader>
1149+
<Form layout="S1 M2 L2 XL2">
1150+
<FormGroup headerText="Personal Data">
1151+
<FormItem labelContent={<Label>Name</Label>}>
1152+
<Input type={InputType.Text} />
1153+
</FormItem>
1154+
<FormItem labelContent={<Label>Address</Label>}>
1155+
<Input type={InputType.Text} />
1156+
</FormItem>
1157+
<FormItem labelContent={<Label>Country</Label>}>
1158+
<Select>
1159+
<Option>Germany</Option>
1160+
<Option>France</Option>
1161+
<Option>Italy</Option>
1162+
</Select>
1163+
</FormItem>
1164+
<FormItem labelContent={<Label>Additional Comment</Label>} className="formAlignLabelStart">
1165+
<TextArea
1166+
rows={5}
1167+
placeholder="The label is aligned to start by setting `<class>::part(label){ align-self: start; }` "
1168+
/>
1169+
</FormItem>
1170+
<FormItem labelContent={<Label>Home address</Label>}>
1171+
<CheckBox checked />
1172+
</FormItem>
1173+
</FormGroup>
1174+
<FormGroup headerText="Company Data">
1175+
<FormItem labelContent={<Label>Company Name</Label>}>
1176+
<Input type={InputType.Text} />
1177+
</FormItem>
1178+
<FormItem labelContent={<Label>Company Address</Label>}>
1179+
<Input type={InputType.Text} />
1180+
</FormItem>
1181+
<FormItem labelContent={<Label>Company City</Label>}>
1182+
<Input type={InputType.Text} />
1183+
</FormItem>
1184+
<FormItem labelContent={<Label>Company Country</Label>}>
1185+
<Input type={InputType.Text} />
1186+
</FormItem>
1187+
<FormItem labelContent={<Label>Number of Employees</Label>}>
1188+
<Input type={InputType.Number} value="5000" disabled />
1189+
</FormItem>
1190+
<FormItem labelContent={<Label>Member of Partner Network</Label>}>
1191+
<CheckBox checked />
1192+
</FormItem>
1193+
</FormGroup>
1194+
<FormGroup headerText="Marketing Data">
1195+
<FormItem labelContent={<Label>Email</Label>}>
1196+
<Input type={InputType.Email} />
1197+
</FormItem>
1198+
<FormItem labelContent={<Label>Company Email</Label>}>
1199+
<Input type={InputType.Email} />
1200+
</FormItem>
1201+
<FormItem labelContent={<Label>I want to receive the newsletter</Label>}>
1202+
<CheckBox />
1203+
</FormItem>
1204+
</FormGroup>
1205+
</Form>
1206+
</ObjectPageHeader>
1207+
);
1208+
10141209
const Footer = (
10151210
<Bar
10161211
data-testid="footer"

0 commit comments

Comments
 (0)