kopia lustrzana https://github.com/shoelace-style/shoelace
test: components/avatar (#529)
* test: introduce first pass test for components/avatar feat: set alt="" on img element * test: resolve img src 404 errors * test: remove bad test * test: test children by assigning nodes... * test: add patches similar to badge patch * style: address typing issues.pull/540/head
rodzic
8c3888da02
commit
898179b645
|
@ -0,0 +1,126 @@
|
||||||
|
import { expect, fixture, html } from '@open-wc/testing';
|
||||||
|
|
||||||
|
import '../../../dist/shoelace.js';
|
||||||
|
import type SlAvatar from './avatar';
|
||||||
|
|
||||||
|
describe('<sl-avatar>', () => {
|
||||||
|
let el: SlAvatar;
|
||||||
|
|
||||||
|
describe('when provided no parameters', async () => {
|
||||||
|
before(async () => {
|
||||||
|
el = await fixture<SlAvatar>(html` <sl-avatar></sl-avatar> `);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes accessibility test', async () => {
|
||||||
|
await expect(el).to.be.accessible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should default to circle styling', async () => {
|
||||||
|
const part = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||||
|
expect(el.getAttribute('shape')).to.eq('circle');
|
||||||
|
expect(part.classList.value.trim()).to.eq('avatar avatar--circle');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when provided an image and alt parameter', async () => {
|
||||||
|
const image =
|
||||||
|
'https://images.unsplash.com/photo-1529778873920-4da4926a72c2?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=80';
|
||||||
|
const alt = 'Gray tabby kitten looking down';
|
||||||
|
before(async () => {
|
||||||
|
el = await fixture<SlAvatar>(html`<sl-avatar image="${image}" alt="${alt}"></sl-avatar>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes accessibility test', async () => {
|
||||||
|
/**
|
||||||
|
* The image element itself is ancillary, because it's parent container contains the
|
||||||
|
* aria-label which dictates what "sl-avatar" is. This also implies that alt text will
|
||||||
|
* resolve to "" when not provided and ignored by readers. This is why we use alt="" on
|
||||||
|
* the image element to pass accessibility.
|
||||||
|
* https://html.spec.whatwg.org/multipage/images.html#ancillary-images
|
||||||
|
*/
|
||||||
|
await expect(el).to.be.accessible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders "image" part, with src and a role of presentation', async () => {
|
||||||
|
const part = el.shadowRoot?.querySelector('[part="image"]') as HTMLImageElement;
|
||||||
|
|
||||||
|
expect(part.getAttribute('src')).to.eq(image);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders the alt attribute in the "base" part', async () => {
|
||||||
|
const part = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||||
|
|
||||||
|
expect(part.getAttribute('aria-label')).to.eq(alt);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when an error occurs when attempting to load the image', async () => {
|
||||||
|
before(async () => {
|
||||||
|
el = await fixture<SlAvatar>(
|
||||||
|
html`<sl-avatar image="data:text/plain;not-an-image-url" alt="${alt}"></sl-avatar>`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not render the "image" part', async () => {
|
||||||
|
const part = el.shadowRoot?.querySelector('[part="image"]') as HTMLImageElement;
|
||||||
|
|
||||||
|
expect(part).not.to.exist;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when provided initials parameter', async () => {
|
||||||
|
const initials = 'SL';
|
||||||
|
before(async () => {
|
||||||
|
el = await fixture<SlAvatar>(html`<sl-avatar initials="${initials}"></sl-avatar>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes accessibility test', async () => {
|
||||||
|
await expect(el).to.be.accessible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders "initials" part, with initials as the text node', async () => {
|
||||||
|
const part = el.shadowRoot?.querySelector('[part="initials"]') as HTMLImageElement;
|
||||||
|
|
||||||
|
expect(part.innerText).to.eq(initials);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
['square', 'rounded', 'circle'].forEach(shape => {
|
||||||
|
describe(`when passed a shape attribute ${shape}`, () => {
|
||||||
|
before(async () => {
|
||||||
|
el = await fixture<SlAvatar>(html`<sl-avatar shape="${shape}"></sl-avatar>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes accessibility test', async () => {
|
||||||
|
await expect(el).to.be.accessible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('appends the appropriate class on the "base" part', async () => {
|
||||||
|
const part = el.shadowRoot?.querySelector('[part="base"]') as HTMLElement;
|
||||||
|
|
||||||
|
expect(el.getAttribute('shape')).to.eq(shape);
|
||||||
|
expect(part.classList.value.trim()).to.eq(`avatar avatar--${shape}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when passed a <span>, on slot "icon"', async () => {
|
||||||
|
before(async () => {
|
||||||
|
el = await fixture<SlAvatar>(html`<sl-avatar><span slot="icon">random content</span></sl-avatar>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('passes accessibility test', async () => {
|
||||||
|
await expect(el).to.be.accessible();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should accept as an assigned child in the shadow root', async () => {
|
||||||
|
const slot = <HTMLSlotElement>el.shadowRoot.querySelector('slot[name=icon]');
|
||||||
|
const childNodes = slot.assignedNodes({ flatten: true });
|
||||||
|
|
||||||
|
expect(childNodes.length).to.eq(1);
|
||||||
|
|
||||||
|
const span = <HTMLElement>childNodes[0];
|
||||||
|
expect(span.innerHTML).to.eq('random content');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -61,7 +61,13 @@ export default class SlAvatar extends LitElement {
|
||||||
`}
|
`}
|
||||||
${this.image && !this.hasError
|
${this.image && !this.hasError
|
||||||
? html`
|
? html`
|
||||||
<img part="image" class="avatar__image" src="${this.image}" @error="${() => (this.hasError = true)}" />
|
<img
|
||||||
|
part="image"
|
||||||
|
class="avatar__image"
|
||||||
|
src="${this.image}"
|
||||||
|
alt=""
|
||||||
|
@error="${() => (this.hasError = true)}"
|
||||||
|
/>
|
||||||
`
|
`
|
||||||
: ''}
|
: ''}
|
||||||
</div>
|
</div>
|
||||||
|
|
Ładowanie…
Reference in New Issue