Accessibility is a critical aspect of web development that ensures your application can be used by everyone, including people with disabilities. Making your Vue apps accessible not only meets legal requirements, but provides a better experience for all users. In this post, we’ll explore how to improve accessibility in Vue applications using Testing Library and jest-axe.
Prerequisites
Before we dive in, make sure you have the following installed in your Vue project:
- @testing-library/vue
- jest-axe
You can add them with:
npm install --save-dev @testing-library/vue jest-axe
Example Component
Let’s look at a simple Vue component that displays an image and some text:
<template>
<div: HTMLAttributes & ReservedProps
div>
<h2: HTMLAttributes & ReservedProps
h2>{{ title?: string | undefined
title }}</h2: HTMLAttributes & ReservedProps
h2>
<p: HTMLAttributes & ReservedProps
p>{{ description?: string | undefined
description }}</p: HTMLAttributes & ReservedProps
p>
<img: ImgHTMLAttributes & ReservedProps
img ImgHTMLAttributes.src?: string | undefined
src="sample_image.jpg" />
</div: HTMLAttributes & ReservedProps
div>
</template>
<script setup lang="ts">
const defineProps: <{
title: StringConstructor;
description: StringConstructor;
}>(props: {
title: StringConstructor;
description: StringConstructor;
}) => {
...;
} (+2 overloads)
Vue `<script setup>` compiler macro for declaring component props. The
expected argument is the same as the component `props` option.
Example runtime declaration:
```js
// using Array syntax
const props = defineProps(['foo', 'bar'])
// using Object syntax
const props = defineProps({
foo: String,
bar: {
type: Number,
required: true
}
})
```
Equivalent type-based declaration:
```ts
// will be compiled into equivalent runtime declarations
const props = defineProps<{
foo?: string
bar: number
}>()
```defineProps({
title: StringConstructor
title: var String: StringConstructor
Allows manipulation and formatting of text strings and determination and location of substrings within strings.String,
description: StringConstructor
description: var String: StringConstructor
Allows manipulation and formatting of text strings and determination and location of substrings within strings.String
})
</script>
Many developers know images should have alt text for accessibility, but how can we ensure we never forget this in production?
Testing with jest-axe
This is where jest-axe comes in. Axe is a leading accessibility testing toolkit used by major tech companies.
To test our component, we can create a test file like this:
import { render } from '@testing-library/vue';
import { axe, toHaveNoViolations } from 'jest-axe';
import { describe, it, expect } from 'vitest'
import MyComponent from './MyComponent.vue';
expect.extend(toHaveNoViolations);
describe('MyComponent', () => {
it('has no accessibility violations', async () => {
const { container } = render(MyComponent, {
props: {
title: 'Sample Title',
description: 'Sample Description',
},
});
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
When we run this test, we’ll get an error like:
FAIL src/components/MyComponent.spec.ts > MyComponent > has no accessibility violations
Error: expect(received).toHaveNoViolations(expected)
Expected the HTML found at $('img') to have no violations:
<img src="sample_image.jpg">
Received:
"Images must have alternate text (image-alt)"
Fix any of the following:
Element does not have an alt attribute
aria-label attribute does not exist or is empty
aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty
Element has no title attribute
Element's default semantics were not overridden with role="none" or role="presentation"
This tells us we need to add an alt attribute to our image. We can fix the component and re-run the test until it passes.
Conclusion
By integrating accessibility testing with tools like Testing Library and jest-axe, we can catch accessibility issues early in the development process. This helps ensure our Vue applications remain usable for everyone. Making accessibility testing part of our CI pipeline allows us to maintain high standards and provide a better experience for all users.