@carbon/ibm-products-web-components
Version:
Carbon for IBM Products Web Components
209 lines (206 loc) • 10.2 kB
JavaScript
/**
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import { describe, it, expect } from 'vitest';
import { html, fixture } from '@open-wc/testing';
import { render } from 'lit';
import { blockClass } from './about-modal.js';
import { carbonPrefix } from '../../globals/settings.js';
/**
* Copyright IBM Corp. 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const logo = html `
<img
src="./_story-assets/example-logo.svg"
alt="Example product or service logo"
style="max-width: 6rem"
/>
`;
const additionalInfo = html `
<p class="c4p__footer-label">Powered by</p>
<img
src="./_story-assets/ansible-logo.png"
alt="Grafana"
class="c4p__footer--tech-logo"
/>
<img
src="./_story-assets/ansible-logo.png"
alt="Ansible"
class="c4p__footer--tech-logo"
/>
<img
src="./_story-assets/js-logo.png"
alt="JavaScript"
class="c4p__footer--tech-logo"
/>
`;
const content = html `This Web site contains proprietary notices and copyright
information, the terms of which must be observed and followed. Please see the
tab entitled 'Copyright and trademark information' for related information. IBM
grants you a non-exclusive, non-transferable, limited permission to access and
display the Web pages within this site as a customer or potential customer of
IBM provided you comply with these Terms of Use, and all copyright, trademark,
and other proprietary notices remain intact.`;
const links = [];
const index = 3;
for (let i = 0; i < index; i++) {
const link = html `<cds-custom-link href="#"> Link action </cds-custom-link>`;
links.push(link);
}
const defaultProps = {
closeIconDescription: 'close',
copyrightText: 'Copyright © IBM Corp. 2020, 2023',
logo: logo,
title: 'IBM Product name',
version: 'Version 0.0.0',
additionalInfo: additionalInfo,
content: content,
links: links,
};
const template = (props = defaultProps) => html `
<c4p-about-modal
open
closeIconDescription=${props.closeIconDescription}
copyrightText=${props.copyrightText}
.logo=${props.logo}
.title=${props.title}
.version=${props.version}
.additionalInfo=${props.additionalInfo}
.content=${props.content}
.links=${props.links}
aria-label="label"
>
</c4p-about-modal>
`;
describe('c4p-about-modal', () => {
it('should render about modal', async () => {
const element = render(template(), document.body);
expect(element).toBeDefined();
});
it('renders a title', async () => {
var _a, _b, _c;
const element = await fixture(template());
expect(element.title).toBe(defaultProps.title);
const headingElement = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-heading`);
expect(headingElement).toBeTruthy();
expect(headingElement === null || headingElement === void 0 ? void 0 : headingElement.shadowRoot).toBeTruthy();
const slot = (_b = headingElement === null || headingElement === void 0 ? void 0 : headingElement.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('slot');
expect(slot).toBeTruthy();
const assignedNodes = (_c = slot === null || slot === void 0 ? void 0 : slot.assignedNodes({ flatten: true })) !== null && _c !== void 0 ? _c : [];
const slottedText = assignedNodes
.filter((node) => node.nodeType === Node.TEXT_NODE)
.map((node) => { var _a; return (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim(); })
.join('');
expect(slottedText).toBe(defaultProps.title);
});
it('renders version', async () => {
var _a, _b, _c, _d;
const element = await fixture(template());
expect(element.version).toBe(defaultProps.version);
const modalBody = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-body`);
expect(modalBody).toBeTruthy();
expect(modalBody === null || modalBody === void 0 ? void 0 : modalBody.shadowRoot).toBeTruthy();
const slot = (_b = modalBody === null || modalBody === void 0 ? void 0 : modalBody.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('slot');
expect(slot).toBeTruthy();
const assignedElements = (_c = slot === null || slot === void 0 ? void 0 : slot.assignedElements({ flatten: true })) !== null && _c !== void 0 ? _c : [];
const modalVersion = assignedElements
.map((el) => el.querySelector(`.${blockClass}__version`))
.find((el) => el !== null);
expect(modalVersion).toBeTruthy();
expect((_d = modalVersion === null || modalVersion === void 0 ? void 0 : modalVersion.textContent) === null || _d === void 0 ? void 0 : _d.trim()).toBe(defaultProps.version);
});
it('renders copyright text', async () => {
var _a, _b, _c, _d;
const element = await fixture(template());
expect(element.copyrightText).toBe(defaultProps.copyrightText);
const modalBody = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-body`);
expect(modalBody).toBeTruthy();
expect(modalBody === null || modalBody === void 0 ? void 0 : modalBody.shadowRoot).toBeTruthy();
const slot = (_b = modalBody === null || modalBody === void 0 ? void 0 : modalBody.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('slot');
expect(slot).toBeTruthy();
const assignedElements = (_c = slot === null || slot === void 0 ? void 0 : slot.assignedElements({ flatten: true })) !== null && _c !== void 0 ? _c : [];
const modalCopyRight = assignedElements
.map((el) => el.querySelector(`.${blockClass}__copyright-text`))
.find((el) => el !== null);
expect(modalCopyRight).toBeTruthy();
expect((_d = modalCopyRight === null || modalCopyRight === void 0 ? void 0 : modalCopyRight.textContent) === null || _d === void 0 ? void 0 : _d.trim()).toBe(defaultProps.copyrightText);
});
it('renders links', async () => {
var _a, _b, _c;
const element = await fixture(template());
const modalBody = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-body`);
expect(modalBody).toBeTruthy();
expect(modalBody === null || modalBody === void 0 ? void 0 : modalBody.shadowRoot).toBeTruthy();
const slot = (_b = modalBody === null || modalBody === void 0 ? void 0 : modalBody.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('slot');
expect(slot).toBeTruthy();
const assignedElements = (_c = slot === null || slot === void 0 ? void 0 : slot.assignedElements({ flatten: true })) !== null && _c !== void 0 ? _c : [];
if (element.links.length > 0) {
const modalLinkContainer = assignedElements
.map((el) => el.querySelector(`.${blockClass}__links-container`))
.find((el) => el !== null);
expect(modalLinkContainer).toBeTruthy();
const links = modalLinkContainer === null || modalLinkContainer === void 0 ? void 0 : modalLinkContainer.querySelectorAll(`${carbonPrefix}-link`);
expect((links === null || links === void 0 ? void 0 : links.length) == (element === null || element === void 0 ? void 0 : element.links.length)).toBeTruthy();
}
});
it('renders additional info', async () => {
var _a;
const element = await fixture(template());
if (element.additionalInfo) {
const modalFooter = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-footer`);
expect(modalFooter).toBeTruthy();
}
});
it('closes modal on clicking close button', async () => {
var _a;
const element = await fixture(template());
const modalClose = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-close-button`);
expect(modalClose).toBeTruthy();
expect(element.open).toBe(true);
modalClose === null || modalClose === void 0 ? void 0 : modalClose.click();
expect(element.open).toBe(false);
});
it('Scrollable body with overflowing content', async () => {
var _a;
const element = await fixture(template());
const container = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-body`);
// Simulate overflow: content fits
Object.defineProperty(container, 'scrollHeight', {
value: 200,
configurable: true,
});
Object.defineProperty(container, 'clientHeight', {
value: 100,
configurable: true,
});
// Manually call _checkOverflow to force the overflow check
element['_checkOverflow']();
await element.updateComplete;
expect(container.classList.contains('c4p--about-modal-scroll-content')).toBe(true);
});
it('No scrollable body if content fits', async () => {
var _a;
const element = await fixture(template());
const container = (_a = element.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`${carbonPrefix}-modal-body`);
// Simulate non-overflow: content fits
Object.defineProperty(container, 'scrollHeight', {
value: 100,
configurable: true,
});
Object.defineProperty(container, 'clientHeight', {
value: 200,
configurable: true,
});
// Manually call _checkOverflow to force the overflow check
element['_checkOverflow']();
await element.updateComplete;
expect(container.classList.contains('c4p--about-modal-scroll-content')).toBe(false);
});
});
//# sourceMappingURL=about-modal.test.js.map