Skip to content

Commit

Permalink
test: add unit tests for popover overlay position
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed May 14, 2024
1 parent cde4b76 commit ea13f5f
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/popover/test/basic.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect } from '@esm-bundle/chai';
import { esc, fixtureSync, nextRender, nextUpdate, outsideClick } from '@vaadin/testing-helpers';
import sinon from 'sinon';
import './not-animated-styles.js';
import '../vaadin-popover.js';

describe('popover', () => {
Expand Down
13 changes: 13 additions & 0 deletions packages/popover/test/not-animated-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

registerStyles(
'vaadin-popover-overlay',
css`
:host([opening]),
:host([closing]),
:host([opening]) [part='overlay'],
:host([closing]) [part='overlay'] {
animation: none !important;
}
`,
);
172 changes: 172 additions & 0 deletions packages/popover/test/position.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { expect } from '@esm-bundle/chai';
import { fixtureSync, nextRender, nextUpdate, oneEvent } from '@vaadin/testing-helpers';
import './not-animated-styles.js';
import '../src/vaadin-popover.js';

describe('position', () => {
let popover, target, overlay;

beforeEach(async () => {
popover = fixtureSync('<vaadin-popover></vaadin-popover>');
popover.renderer = (root) => {
root.textContent = 'Content';
};
target = fixtureSync('<div style="width: 100px; height: 100px; margin: 100px; outline: 1px solid red;"></div>');
popover.target = target;
await nextRender();
overlay = popover.shadowRoot.querySelector('vaadin-popover-overlay');
});

// Overlay above the target (position="top-*")
function assertPlacedAbove(overlayRect, targetRect) {
expect(overlayRect.bottom).to.be.closeTo(targetRect.top, 1);
}

// Overlay below the target (position="bottom-*")
function assertPlacedBelow(overlayRect, targetRect) {
expect(overlayRect.top).to.be.closeTo(targetRect.bottom, 1);
}

// Overlay before the target (position="start-*")
function assertPlacedBefore(overlayRect, targetRect, dir) {
const x1 = dir === 'rtl' ? 'left' : 'right';
const x2 = dir === 'rtl' ? 'right' : 'left';
expect(overlayRect[x1]).to.be.closeTo(targetRect[x2], 1);
}

// Overlay after the target (position="end-*")
function assertPlacedAfter(overlayRect, targetRect, dir) {
const x1 = dir === 'rtl' ? 'right' : 'left';
const x2 = dir === 'rtl' ? 'left' : 'right';
expect(overlayRect[x1]).to.be.closeTo(targetRect[x2], 1);
}

function assertStartAligned(overlayRect, targetRect, dir) {
const x = dir === 'rtl' ? 'right' : 'left';
expect(overlayRect[x]).to.be.closeTo(targetRect[x], 1);
}

function assertEndAligned(overlayRect, targetRect, dir) {
const x = dir === 'rtl' ? 'left' : 'right';
expect(overlayRect[x]).to.be.closeTo(targetRect[x], 1);
}

function assertTopAligned(overlayRect, targetRect) {
expect(overlayRect.top).to.be.closeTo(targetRect.top, 1);
}

function assertBottomAligned(overlayRect, targetRect) {
expect(overlayRect.bottom).to.be.closeTo(targetRect.bottom, 1);
}

function assertCenteredHorizontally(overlayRect, targetRect, dir) {
const coord = dir === 'rtl' ? 'right' : 'left';
const offset = targetRect.width / 2 - overlayRect.width / 2;
expect(overlayRect[coord]).to.be.closeTo(targetRect[coord] + (dir === 'rtl' ? offset * -1 : offset), 1);
}

function assertCenteredVertically(overlayRect, targetRect) {
const offset = targetRect.height / 2 - overlayRect.height / 2;
expect(overlayRect.top).to.be.closeTo(targetRect.top + offset, 1);
}

describe('default', () => {
it('should not set position property value by default', () => {
expect(popover.position).to.be.undefined;
});

it('should set overlay position to bottom by default', () => {
expect(overlay.position).to.be.equal('bottom');
});
});

[
{
position: 'top-start',
assertPlaced: assertPlacedAbove,
assertAligned: assertStartAligned,
},
{
position: 'top',
assertPlaced: assertPlacedAbove,
assertAligned: assertCenteredHorizontally,
},
{
position: 'top-end',
assertPlaced: assertPlacedAbove,
assertAligned: assertEndAligned,
},
{
position: 'bottom-start',
assertPlaced: assertPlacedBelow,
assertAligned: assertStartAligned,
},
{
position: 'bottom',
assertPlaced: assertPlacedBelow,
assertAligned: assertCenteredHorizontally,
},
{
position: 'bottom-end',
assertPlaced: assertPlacedBelow,
assertAligned: assertEndAligned,
},
{
position: 'start-top',
assertPlaced: assertPlacedBefore,
assertAligned: assertTopAligned,
},
{
position: 'start',
assertPlaced: assertPlacedBefore,
assertAligned: assertCenteredVertically,
},
{
position: 'start-bottom',
assertPlaced: assertPlacedBefore,
assertAligned: assertBottomAligned,
},
{
position: 'end-top',
assertPlaced: assertPlacedAfter,
assertAligned: assertTopAligned,
},
{
position: 'end',
assertPlaced: assertPlacedAfter,
assertAligned: assertCenteredVertically,
},
{
position: 'end-bottom',
assertPlaced: assertPlacedAfter,
assertAligned: assertBottomAligned,
},
].forEach(({ position, assertPlaced, assertAligned }) => {
describe(position, () => {
['ltr', 'rtl'].forEach((dir) => {
describe(`${position} ${dir}`, () => {
before(() => {
document.documentElement.setAttribute('dir', dir);
});

after(() => {
document.documentElement.removeAttribute('dir');
});

it(`should position overlay against target ${position} with ${dir}`, async () => {
popover.position = position;
await nextUpdate(popover);

target.click();
await oneEvent(overlay, 'vaadin-overlay-open');
const overlayRect = overlay.$.overlay.getBoundingClientRect();
const targetRect = target.getBoundingClientRect();

assertPlaced(overlayRect, targetRect, dir);
assertAligned(overlayRect, targetRect, dir);
});
});
});
});
});
});

0 comments on commit ea13f5f

Please sign in to comment.