lion/packages/ui/components/pagination/test/lion-pagination.test.js
Tudor Gradinaru ef0af0e41c
fix(pagination): remove unnecessary ellipsis when count equals visiblePages + 2 (#2624)
* fix(pagination): remove unnecessary ellipsis when count equals visiblePages + 1

Fixes #2589

- Changed condition from  to
- This allows one extra page to be displayed without ellipsis (e.g., [1,2,3,4,5,6] instead of [1,2,3,4,5,'...',6])
- Added test case to verify ellipsis is not shown when count=6 and visiblePages=5

* Update packages/ui/components/pagination/src/LionPagination.js

Co-authored-by: gerjanvangeest <gerjanvangeest@users.noreply.github.com>

* test: add additional ellipsis display tests

- Add test for count=7 (visiblePages + 2) without ellipsis
- Add test for count=8 (visiblePages + 3) with ellipsis
- Update condition to visiblePages + 2 to allow both count=6 and count=7 without ellipsis

---------

Co-authored-by: gerjanvangeest <gerjanvangeest@users.noreply.github.com>
2025-11-24 09:17:41 +01:00

208 lines
8.4 KiB
JavaScript

import { fixture as _fixture, expect } from '@open-wc/testing';
import { html } from 'lit/static-html.js';
import sinon from 'sinon';
import '@lion/ui/define/lion-pagination.js';
/**
* @typedef {import('../src/LionPagination.js').LionPagination} LionPagination
* @typedef {import('lit').TemplateResult} TemplateResult
*/
const fixture = /** @type {(arg: TemplateResult) => Promise<LionPagination>} */ (_fixture);
describe('Pagination', () => {
it('has states for count and current', async () => {
const el = await fixture(html` <lion-pagination count="4"></lion-pagination> `);
expect(el.getAttribute('count')).to.equal('4');
expect(el.getAttribute('current')).to.equal('1');
el.count = 8;
el.current = 2;
await el.updateComplete;
expect(el.getAttribute('count')).to.equal('8');
expect(el.getAttribute('current')).to.equal('2');
});
it('disables the previous button if on first page', async () => {
const el = await fixture(html` <lion-pagination count="4"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
expect(buttons[0]).to.has.attribute('disabled');
});
it('disables the next button if on last page', async () => {
const el = await fixture(html` <lion-pagination count="4" current="4"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
expect(buttons[buttons.length - 1]).to.has.attribute('disabled');
});
describe('User interaction', () => {
it('can go to previous page with previous button', async () => {
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
buttons[0].click();
expect(el.current).to.equal(1);
});
it('can go to next page with next button', async () => {
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
buttons[buttons.length - 1].click();
expect(el.current).to.equal(3);
});
it('goes to the page when clicking on its button', async () => {
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
buttons[5].click();
expect(el.current).to.equal(5);
});
it('fires current-changed event when interacting with the pagination', async () => {
const changeSpy = sinon.spy();
const el = await fixture(html`
<lion-pagination count="6" current="2" @current-changed=${changeSpy}></lion-pagination>
`);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
const previous = buttons[0];
const next = buttons[buttons.length - 1];
const page5 = buttons[5];
previous.click();
expect(changeSpy).to.have.callCount(1);
next.click();
expect(changeSpy).to.have.callCount(2);
page5.click();
expect(changeSpy).to.have.callCount(3);
el.current = 3;
expect(changeSpy).to.have.callCount(4);
});
it('does NOT fire current-changed event when clicking on a current page number', async () => {
const changeSpy = sinon.spy();
const el = await fixture(html`
<lion-pagination count="6" current="2" @current-changed=${changeSpy}></lion-pagination>
`);
const page2 = /** @type {HTMLElement} */ (
el.shadowRoot?.querySelector("button[aria-current='true']")
);
page2.click();
expect(changeSpy).to.not.be.called;
expect(el.current).to.equal(2);
});
it('should announce next and previous page using `next()` and `previous()`', async () => {
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
expect(buttons[2].getAttribute('aria-live')).to.equal('polite');
el.next();
await el.updateComplete;
expect(buttons[3].getAttribute('aria-live')).to.equal('polite');
expect(buttons[2].getAttribute('aria-live')).to.equal('off');
el.previous();
await el.updateComplete;
expect(buttons[3].getAttribute('aria-live')).to.equal('off');
expect(buttons[2].getAttribute('aria-live')).to.equal('polite');
});
it('should goto next and previous page using `next()` and `previous()`', async () => {
const el = await fixture(html` <lion-pagination count="6" current="2"></lion-pagination> `);
el.next();
expect(el.current).to.equal(3);
el.previous();
expect(el.current).to.equal(2);
});
it('should goto first and last page using `first()` and `last()`', async () => {
const el = await fixture(html` <lion-pagination count="5" current="2"></lion-pagination> `);
expect(el.current).to.equal(2);
el.first();
expect(el.current).to.equal(1);
el.last();
expect(el.current).to.equal(5);
});
it('should goto 7 page using `goto()`', async () => {
const el = await fixture(html` <lion-pagination count="10" current="2"></lion-pagination> `);
expect(el.current).to.equal(2);
el.goto(7);
expect(el.current).to.equal(7);
});
});
describe('Accessibility', () => {
it('sets aria-current to the current page', async () => {
const el = await fixture(html` <lion-pagination count="3"></lion-pagination> `);
const buttons = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('button'),
);
// button[0] is the previous button
expect(buttons[1].getAttribute('aria-current')).to.equal('true');
expect(buttons[2].getAttribute('aria-current')).to.equal('false');
expect(buttons[3].getAttribute('aria-current')).to.equal('false');
el.current = 2;
await el.updateComplete;
expect(buttons[1].getAttribute('aria-current')).to.equal('false');
expect(buttons[2].getAttribute('aria-current')).to.equal('true');
expect(buttons[3].getAttribute('aria-current')).to.equal('false');
});
});
describe('Ellipsis display', () => {
it('should not show ellipsis when count is visiblePages + 1 (count=6, visiblePages=5)', async () => {
const el = await fixture(html` <lion-pagination count="6" current="1"></lion-pagination> `);
const navItems = Array.from(/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li'));
// Check that no ellipsis is rendered (no <span> elements with '...')
const spans = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li span'),
);
expect(spans.length).to.equal(0);
// There should be 8 nav items: previous button + 6 page buttons + next button
expect(navItems.length).to.equal(8);
});
it('should not show ellipsis when count is visiblePages + 2 (count=7, visiblePages=5)', async () => {
const el = await fixture(html` <lion-pagination count="7" current="1"></lion-pagination> `);
// Check that no ellipsis is rendered (no <span> elements with '...')
const spans = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li span'),
);
expect(spans.length).to.equal(0);
// There should be 9 nav items: previous button + 7 page buttons + next button
const navItems = Array.from(/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li'));
expect(navItems.length).to.equal(9);
});
it('should show ellipsis when count is visiblePages + 3 (count=8, visiblePages=5)', async () => {
const el = await fixture(html` <lion-pagination count="8" current="1"></lion-pagination> `);
// Check that ellipsis is rendered (should have <span> elements with '...')
const spans = Array.from(
/** @type {ShadowRoot} */ (el.shadowRoot).querySelectorAll('li span'),
);
expect(spans.length).to.be.greaterThan(0);
// Verify the ellipsis contains '...'
const ellipsisText = Array.from(spans).map(span => span.textContent);
expect(ellipsisText).to.include('...');
});
});
});