-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
I'm running into issues writing a test for a "Media Selector" component. It looks like this:
It's a set of buttons, with each button containing an image.
Here's the component markup:
import { CheckMark } from '../../icons/check-mark';
import { MediaSelectorItem } from './media-selector-item';
import './media-selector.scss';
export function MediaSelector({
selectedItem,
items,
onChange,
}: {
selectedItem: MediaSelectorItem;
items: MediaSelectorItem[];
onChange: (value: MediaSelectorItem) => void;
}) {
return (
<div className="api-x_c-media-selector">
{items.map((item: MediaSelectorItem) => {
// If a custom aspect ratio has been passed in, apply it
const imageStyles = item.aspectRatio
? { '--api-x_media-aspect-ratio': item.aspectRatio }
: {};
return (
<button
type="button"
className="api-x_c-media-selector__button"
aria-pressed={(item.value === selectedItem.value).toString()}
data-value={item.value}
key={item.value}
onClick={() => onChange(item)}
>
<CheckMark svgClass="api-x_c-media-selector__check" />
<img
style={imageStyles}
className="api-x_c-media-selector__image"
src={item.src}
alt={item.alt}
/>
</button>
);
})}
</div>
);
}And here's my test:
import { withBrowser, PleasantestUtils } from 'pleasantest';
async function setup(utils: PleasantestUtils) {
await utils.runJS(`
import { render } from 'preact';
import { useState } from 'preact/hooks';
import { Root } from '../root/root';
import { MediaSelector } from './media-selector';
// Preact's render function doesn't clear this properly
document.body.innerHTML = '';
function MediaSelectorExample() {
const items = [
{
src: 'https://cloudinary-marketing-res.cloudinary.com/image/upload/h_160/sneakers-wide.jpg',
alt: 'sneakers',
value: 'sneakers-wide'
},
{
src: 'https://cloudinary-marketing-res.cloudinary.com/image/upload/h_160/car.jpg',
alt: 'car',
value: 'car'
}
];
const [option, setOption] = useState(items[0]);
return (
<Root>
<MediaSelector onChange={setOption} selectedItem={option} items={items} />
</Root>
);
}
render((
<MediaSelectorExample />
), document.body);
`);
}
test(
'Confirm the buttons are pressed correctly',
withBrowser(async ({ utils, screen, user }) => {
await setup(utils);
const firstItem = await screen.getByRole('button', {
name: 'sneakers',
});
const secondItem = await screen.getByRole('button', {
name: 'car',
});
// We set the first item as selected
await expect(firstItem).toHaveAttribute('aria-pressed', 'true');
await expect(secondItem).toHaveAttribute('aria-pressed', 'false');
// I'm not sure why this is necessary.
// I'm opening a Pleasantest issue to discuss.
await new Promise((resolve) => setTimeout(resolve, 500));
// Clicking the first item should do nothing. It's already selected
await user.click(firstItem, { force: true, targetSize: false });
// The first item should still be pressed
await expect(firstItem).toHaveAttribute('aria-pressed', 'true');
await expect(secondItem).toHaveAttribute('aria-pressed', 'false');
// Clicking the second item should select it
await user.click(secondItem, { force: true, targetSize: false });
// The user clicked the second item. It should be selected
await expect(secondItem).toHaveAttribute('aria-pressed', 'true');
await expect(firstItem).toHaveAttribute('aria-pressed', 'false');
})
);This test is passing, but only because I've put a 500ms timeout in the middle of it. If I remove this, then I can't click the buttons.
I ran into a few different issues:
- First off it said the buttons were too small or not visibly.
- I figured this was because the image hadn't loaded and the button had no width. I added an aspect ratio to the image CSS but it still didn't work
- Then I added
{ force: true, targetSize: false }. At this point it worked sometimes but failed other times with a different error:
- Then it said the buttons are "either not clickable or not an HTMLElement"
- At this point I added the timeout and it fixed it.
I'm not sure what's going on. This is a private repo but you should have access. Here's the PR: https://github.com/cloudfour/cld-api-explorer/pull/9
Let me know if you need more info or would like to troubleshoot together.
Thanks!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
