Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ export default defineConfig({
excludeSpecPattern: ['**/e2e/**'],
},
includeShadowDom: true,
retries: {
runMode: 1,
openMode: 0,
},
viewportWidth: 1920,
viewportHeight: 1080,
video: false,
screenshotOnRunFailure: false,
scrollBehavior: false,
allowCypressEnv: false,
});
38 changes: 38 additions & 0 deletions cypress/support/commands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,41 @@ Cypress.Commands.add('shouldNeverHaveAttribute', { prevSubject: 'element' }, (su
}, observerTime);
});
});

// Cypress 16 counts scrolled-out elements as visible, so `not.be.visible` no longer works here.
/**
* Asserts the subject is present but scrolled/clipped out of its scroll container (geometry only, no occlusion).
*
* @example
* cy.findByText('Off-screen section').should('be.scrolledOutOfView');
*/
chai.Assertion.addProperty('scrolledOutOfView', function (this: Chai.AssertionStatic) {
const subject = this._obj as JQuery<HTMLElement> | HTMLElement;
const el = ((subject as JQuery<HTMLElement>).jquery ? (subject as JQuery<HTMLElement>)[0] : subject) as HTMLElement;
const win = el.ownerDocument.defaultView!;

const rect = el.getBoundingClientRect();
const clip = { top: 0, left: 0, bottom: win.innerHeight, right: win.innerWidth };

for (let node = el.parentElement; node; node = node.parentElement) {
const { overflowX, overflowY } = win.getComputedStyle(node);
if (/(auto|scroll|hidden|clip)/.test(`${overflowX} ${overflowY}`)) {
const r = node.getBoundingClientRect();
clip.top = Math.max(clip.top, r.top);
clip.left = Math.max(clip.left, r.left);
clip.bottom = Math.min(clip.bottom, r.bottom);
clip.right = Math.min(clip.right, r.right);
}
}

const outOfView =
rect.bottom <= clip.top || rect.top >= clip.bottom || rect.right <= clip.left || rect.left >= clip.right;

this.assert(
outOfView,
'expected #{this} to be scrolled/clipped out of its scroll container',
'expected #{this} not to be scrolled/clipped out of its scroll container',
true,
outOfView,
);
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"@vitejs/plugin-react": "6.1.1",
"chromatic": "17.8.0",
"cssnano": "9.0.2",
"cypress": "15.18.1",
"cypress": "16.0.0",
"cypress-real-events": "1.15.0",
"dedent": "1.7.2",
"documentation": "14.0.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/cypress-commands/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"peerDependencies": {
"@ui5/webcomponents": "~2.26.0",
"@ui5/webcomponents-base": "~2.26.0",
"cypress": "^12 || ^13 || ^14 || ^15"
"cypress": "^12 || ^13 || ^14 || ^15 || ^16"
},
"peerDependenciesMeta": {
"@ui5/webcomponents": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ describe('AnalyticalTable', () => {
);
cy.findByRole('grid').should('have.attr', 'data-per-page', '3');
cy.findByText('X').should('be.visible');
cy.findByText('C').should('not.be.visible');
cy.get('[data-empty-row]').should('not.be.visible').should('have.length', 1);
cy.findByText('C').should('be.scrolledOutOfView');
cy.get('[data-empty-row]').should('be.scrolledOutOfView').should('have.length', 1);
},
);
[AnalyticalTableVisibleRowCountMode.Auto, AnalyticalTableVisibleRowCountMode.AutoWithEmptyRows].forEach(
Expand All @@ -312,7 +312,7 @@ describe('AnalyticalTable', () => {
);
cy.findByRole('grid').should('have.attr', 'data-per-page', '99'); //rows(99*44) + header(44) = 4400
cy.findByText('Name-98').should('be.visible');
cy.findByText('Name-99').should('not.be.visible');
cy.findByText('Name-99').should('be.scrolledOutOfView');
cy.get('[data-empty-row]').should('not.exist');
},
);
Expand Down Expand Up @@ -349,7 +349,7 @@ describe('AnalyticalTable', () => {
);
cy.findByRole('grid').should('have.attr', 'data-per-page', '3');
cy.findByText('X').should('be.visible');
cy.findByText('C').should('not.be.visible');
cy.findByText('C').should('be.scrolledOutOfView');
},
);

Expand All @@ -363,7 +363,7 @@ describe('AnalyticalTable', () => {
);
cy.findByRole('grid').should('have.attr', 'data-per-page', '15');
cy.findByText('Name-14').should('be.visible');
cy.findByText('Name-15').should('not.be.visible');
cy.findByText('Name-15').should('be.scrolledOutOfView');

cy.mount(
<AnalyticalTable
Expand All @@ -375,7 +375,7 @@ describe('AnalyticalTable', () => {
);
cy.findByRole('grid').should('have.attr', 'data-per-page', '20');
cy.findByText('Name-19').should('be.visible');
cy.findByText('Name-20').should('not.be.visible');
cy.findByText('Name-20').should('be.scrolledOutOfView');

cy.mount(
<AnalyticalTable
Expand All @@ -387,20 +387,20 @@ describe('AnalyticalTable', () => {
);
cy.findByRole('grid').should('have.attr', 'data-per-page', '10');
cy.findByText('Name-9').should('be.visible');
cy.findByText('Name-10').should('not.be.visible');
cy.findByText('Name-10').should('be.scrolledOutOfView');
cy.findByTitle('Drag to resize')
.trigger('mousedown')
.trigger('mousemove', { pageY: 742, force: true })
.trigger('mouseup', { pageY: 742 });
cy.findByRole('grid').should('have.attr', 'data-per-page', '15');
cy.findByText('Name-14').should('be.visible');
cy.findByText('Name-15').should('not.be.visible');
cy.findByText('Name-15').should('be.scrolledOutOfView');
cy.findByTitle('Drag to resize').realMouseDown();
cy.findByTitle('Drag to resize').realMouseMove(0, -540, { scrollBehavior: false });
cy.get('body').realMouseUp({ position: { x: 100, y: 200 } });
cy.findByRole('grid').should('have.attr', 'data-per-page', '3');
cy.findByText('Name-2').should('be.visible');
cy.findByText('Name-3').should('not.be.visible');
cy.findByText('Name-3').should('be.scrolledOutOfView');
});

it('Auto row count: no double vertical scrollbar when horizontally scrollable', () => {
Expand Down Expand Up @@ -616,10 +616,10 @@ describe('AnalyticalTable', () => {

cy.mount(<ScrollTable scrollFn="horizontalScrollToItem" args={[1, 'start']} onTableScroll={scroll} />);
cy.findByText('A').should('be.visible');
cy.findByText('28').should('not.be.visible');
cy.findByText('28').should('be.scrolledOutOfView');
cy.findByText('Click').click();
cy.findByText('28').should('be.visible');
cy.findByText('A').should('not.be.visible');
cy.findByText('A').should('be.scrolledOutOfView');

cy.mount(<ScrollTable scrollFn="horizontalScrollTo" args={[20]} onTableScroll={scroll} />);
cy.findByText('Click').click();
Expand Down Expand Up @@ -749,7 +749,7 @@ describe('AnalyticalTable', () => {

// column filter + select
cy.findByText('Name').click();
cy.get(`[ui5-input][show-clear-icon]`).typeIntoUi5Input('Flowers Mcfarland', { force: true });
cy.get(`[ui5-input][show-clear-icon]`).typeIntoUi5Input('Flowers Mcfarland', { force: true, delay: 10 });
cy.get('@filter').should('have.callCount', 17);
cy.get('@filter').should('have.been.calledWithMatch', {
value: 'Flowers Mcfarland',
Expand Down Expand Up @@ -1804,7 +1804,7 @@ describe('AnalyticalTable', () => {
cy.get('[data-empty-row="true"]').should('not.exist');
cy.findByText('Data 10').click();
cy.findByText('Rows: 10').should('be.visible');
cy.get('[data-empty-row="true"]').should('exist').should('not.be.visible');
cy.get('[data-empty-row="true"]').should('exist').and('be.scrolledOutOfView');
cy.findByTestId('scrollInput').typeIntoUi5Input('11{enter}', { force: true });
cy.findByText('Rows: 60').should('be.visible');
});
Expand Down Expand Up @@ -2666,7 +2666,7 @@ describe('AnalyticalTable', () => {
);
cy.wait(300);

cy.findByText('SubComponent 1').should('exist').and('not.be.visible');
cy.findByText('SubComponent 1').should('exist').and('be.scrolledOutOfView');
cy.findByTitle('Expand Node').should('not.exist');
cy.findByTitle('Collapse Node').should('not.exist');
expectBoundedAndReset();
Expand Down Expand Up @@ -2701,15 +2701,15 @@ describe('AnalyticalTable', () => {
);
cy.findByText('A').should('be.visible');
cy.findByText('X').should('be.visible');
cy.findByText('C').should('not.be.visible');
cy.findByText('C').should('be.scrolledOutOfView');
cy.get('[aria-rowindex="2"] > [aria-colindex="1"] > [title="Expand Node"] > [ui5-button]').click();
cy.findByText('A').should('be.visible');
cy.findByText('X').should('be.visible');
cy.findByText('C').should('not.be.visible');
cy.findByText('C').should('be.scrolledOutOfView');
cy.get('[aria-rowindex="3"] > [aria-colindex="1"] > [title="Expand Node"] > [ui5-button]').click();
cy.findByText('A').should('be.visible');
cy.findByText('X').should('be.visible');
cy.findByText('C').should('not.be.visible');
cy.findByText('C').should('be.scrolledOutOfView');
if (zoom === '1') {
// Cypress' scrollTo('bottom') uses BCR-style coords and doesn't fire onLoadMore reliably under CSS zoom; verified at zoom=1 only
cy.get('[data-component-name="AnalyticalTableBody"]').scrollTo('bottom');
Expand Down Expand Up @@ -4269,7 +4269,7 @@ describe('AnalyticalTable', () => {
};
cy.mount(<ScrollTo />);
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('Name-12').should('be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('Name-11').should('not.be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('Name-11').should('be.scrolledOutOfView');

const ScrollToItem = () => {
const tableRef = useRef(null);
Expand All @@ -4280,7 +4280,7 @@ describe('AnalyticalTable', () => {
};
cy.mount(<ScrollToItem />);
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('Name-12').should('be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('Name-11').should('not.be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('Name-11').should('be.scrolledOutOfView');

const cols = [
...columns,
Expand All @@ -4298,7 +4298,7 @@ describe('AnalyticalTable', () => {
};
cy.mount(<ScrollToHorizontal />);
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('13').should('be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('12').should('not.be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('12').should('be.scrolledOutOfView');

const ScrollToItemHorizontal = () => {
const tableRef = useRef(null);
Expand All @@ -4315,17 +4315,17 @@ describe('AnalyticalTable', () => {
};
cy.mount(<ScrollToItemHorizontal />);
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('13').should('be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('12').should('not.be.visible');
cy.get('[data-component-name="AnalyticalTableContainer"]').findByText('12').should('be.scrolledOutOfView');
});
}

it('additionalEmptyRowsCount', () => {
cy.mount(<AnalyticalTable data={data} columns={columns} minRows={4} />);
cy.get('[data-empty-row]').should('not.exist');
cy.mount(<AnalyticalTable data={data} columns={columns} minRows={4} additionalEmptyRowsCount={1} />);
cy.get('[data-empty-row]').should('exist').and('not.be.visible');
cy.get('[data-empty-row]').should('exist').and('be.scrolledOutOfView');
cy.mount(<AnalyticalTable data={data} columns={columns} minRows={4} additionalEmptyRowsCount={5} />);
cy.get('[data-empty-row]').should('exist').and('have.length', 5).and('not.be.visible');
cy.get('[data-empty-row]').should('exist').and('have.length', 5).and('be.scrolledOutOfView');
cy.get('[data-component-name="AnalyticalTableBody"]').scrollTo('bottom');
cy.get('[data-empty-row]').should('exist').and('have.length', 5).and('be.visible');
});
Expand Down
26 changes: 13 additions & 13 deletions packages/main/src/components/ObjectPage/ObjectPage.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ describe('ObjectPage', () => {
);
cy.wait(200);

cy.findByText('Employment').should('not.be.visible');
cy.findByText('Employment').should('be.scrolledOutOfView');
cy.findByText('Test').should('be.visible');

cy.get('[ui5-tabcontainer]').findUi5TabByText('Employment').realClick();
Expand Down Expand Up @@ -420,7 +420,7 @@ describe('ObjectPage', () => {
);
cy.wait(100);

cy.findByText('Employment').should('not.be.visible');
cy.findByText('Employment').should('be.scrolledOutOfView');
cy.findByText('Test').should('be.visible');
cy.findByTestId('footer').should('be.visible');

Expand Down Expand Up @@ -631,7 +631,7 @@ describe('ObjectPage', () => {
cy.realPress('Enter');
cy.wait(500);
cy.findByText('Job Relationship').should('be.visible');
cy.findByText('Job Information').should('not.be.visible');
cy.findByText('Job Information').should('be.scrolledOutOfView');

cy.mount(
<ObjectPage
Expand Down Expand Up @@ -665,7 +665,7 @@ describe('ObjectPage', () => {
cy.wait(500);

cy.get('[ui5-tabcontainer]').contains('Job Relationship').click({ force: true });
cy.findByText('Job Information').should('not.be.visible');
cy.findByText('Job Information').should('be.scrolledOutOfView');
cy.findByText('Job Relationship').should('be.visible');
cy.findByTestId('footer').should('be.visible');
});
Expand Down Expand Up @@ -1258,7 +1258,7 @@ describe('ObjectPage', () => {
if (mode === ObjectPageMode.IconTabBar) {
cy.findByText('Content1').should('not.exist');
} else {
cy.findByText('Content1').should('not.be.visible');
cy.findByText('Content1').should('be.scrolledOutOfView');
}
cy.findByText('Content2').should('be.visible');
cy.get('[ui5-tabcontainer]').findUi5TabByText('test2').should('have.attr', 'aria-selected', 'true');
Expand Down Expand Up @@ -1338,7 +1338,7 @@ describe('ObjectPage', () => {
);

cy.findByText('employment-job-relationship-content').should('be.visible');
cy.findByText('Job Information').should('not.be.visible');
cy.findByText('Job Information').should('be.scrolledOutOfView');
cy.get('[ui5-tabcontainer]').findUi5TabByText('Employment').should('have.attr', 'aria-selected', 'true');

cy.mount(
Expand All @@ -1349,7 +1349,7 @@ describe('ObjectPage', () => {
if (mode === 'IconTabBar') {
cy.findByText('test-content').should('not.exist');
} else {
cy.findByText('test-content').should('not.be.visible');
cy.findByText('test-content').should('be.scrolledOutOfView');
}
cy.get('[ui5-tabcontainer]').findUi5TabByText('Personal').should('have.attr', 'aria-selected', 'true');

Expand All @@ -1363,15 +1363,15 @@ describe('ObjectPage', () => {
if (mode === 'IconTabBar') {
cy.findByText('personal-connect-content').should('not.exist');
} else {
cy.findByText('personal-connect-content').should('not.be.visible');
cy.findByText('personal-connect-content').should('be.scrolledOutOfView');
}
cy.get('[ui5-tabcontainer]').findUi5TabByText('Goals').should('have.attr', 'aria-selected', 'true');

cy.get('[ui5-tabcontainer]').findUi5TabByText('Personal').click();
if (mode === 'IconTabBar') {
cy.findByText('test-content').should('not.exist');
} else {
cy.findByText('test-content').should('not.be.visible');
cy.findByText('test-content').should('be.scrolledOutOfView');
}
cy.findByText('personal-connect-content').should('be.visible');
cy.get('[ui5-tabcontainer]').findUi5TabByText('Personal').should('have.attr', 'aria-selected', 'true');
Expand All @@ -1384,7 +1384,7 @@ describe('ObjectPage', () => {
if (mode === 'IconTabBar') {
cy.findByText('personal-connect-content').should('not.exist');
} else {
cy.findByText('personal-connect-content').should('not.be.visible');
cy.findByText('personal-connect-content').should('be.scrolledOutOfView');
}
cy.findByText('goals-content').should('be.visible');
cy.get('[ui5-tabcontainer]').findUi5TabByText('Goals').should('have.attr', 'aria-selected', 'true');
Expand All @@ -1400,7 +1400,7 @@ describe('ObjectPage', () => {

cy.findByText('Select Payment Information').click();
cy.findByText('personal-payment-information-content').should('be.visible');
cy.findByText('personal-connect-content').should('not.be.visible');
cy.findByText('personal-connect-content').should('be.scrolledOutOfView');
cy.get('[ui5-tabcontainer]').findUi5TabByText('Personal').should('have.attr', 'aria-selected', 'true');
if (mode !== 'IconTabBar') {
cy.get('@change').should('have.callCount', callCount);
Expand Down Expand Up @@ -1917,7 +1917,7 @@ describe('ObjectPage', () => {
cy.findByText('Personal').should('be.visible').parent().should('have.css', 'position', 'static');
cy.findByText('Connect').should('be.visible').parent().should('have.css', 'position', 'sticky');
cy.findByTestId('op').scrollTo(0, 2500);
cy.findByText('Goals').should('not.be.visible');
cy.findByText('Goals').should('be.scrolledOutOfView');
cy.findByText('Payment Information').should('be.visible');
cy.get('[ui5-tabcontainer]').findUi5TabByText('Custom Header Section One').click();
cy.findByText('Custom Header Section One').should('be.visible').parent().should('have.css', 'position', 'sticky');
Expand All @@ -1928,7 +1928,7 @@ describe('ObjectPage', () => {
cy.findByText('Custom Header Section Two').should('be.visible').parent().should('have.css', 'position', 'static');
cy.findByText('Subsection1').should('be.visible').parent().should('have.css', 'position', 'sticky');
cy.findByTestId('op').scrollTo(0, 4000);
cy.findByText('Custom Header Section Two').should('not.be.visible');
cy.findByText('Custom Header Section Two').should('be.scrolledOutOfView');
cy.findByText('Subsection1').should('be.visible');
});

Expand Down
Loading
Loading