Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: address some accessibility violations #30358

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/app/src/components/FileMatch.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@
v-if="expanded"
v-model="localExtensionPattern"
class="ml-[12px]"
:aria-label="t('components.fileSearch.byFilenameInput') in search"
:placeholder="t('components.fileSearch.byExtensionInput')"
/>
<FileMatchInput
v-else
v-model="localPattern"
aria-label="file-name-input"
:aria-label="t('components.fileSearch.byFilenameInput')"
:placeholder="t('components.fileSearch.byFilenameInput')"
/>
</div>
Expand All @@ -72,6 +73,7 @@
<i-cy-magnifying-glass_x16 class="mr-[8px] ml-[12px] inline-block icon-light-gray-50 icon-dark-gray-500 group-focus-within:icon-light-indigo-50 group-focus-within:icon-dark-indigo-400" />
<FileMatchInput
v-model="localPattern"
:aria-label="t('components.fileSearch.byFilenameInput')"
:placeholder="t('components.fileSearch.byFilenameInput')"
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/components/FileMatchInput.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('<FileMatchInput />', () => {
}

cy.mount(() => (<div class="p-12">
<FileMatchInput modelValue={inputText.value} {...methods} />
<FileMatchInput aria-label="search for file" modelValue={inputText.value} {...methods} />
</div>))
.get('input[type=search]').should('have.value', initialText)
.clear().type(newText)
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/components/SpecPatterns.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
:gql="props.gql"
>
<button
aria-label="open in IDE"
class="flex outline-transparent text-indigo-500 gap-[8px] items-center group"
@click="onClick"
>
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/runner/SnapshotHighlightControls.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<template>
<div class="rounded flex font-medium bg-gray-900 py-[2px] px-[12px] text-gray-200 text-[14px] leading-[20px] gap-[8px] items-center">
<Switch
name="toggle-highlights"
label-id="toggle-highlights"
:value="props.value"
size="sm"
@update="emits('toggle')"
/>
<label
for="toggle-highlights"
id="toggle-highlights"
class="cursor-pointer"
>{{ t('runner.snapshot.highlightsLabel') }}
</label>
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/runner/SpecRunnerHeaderOpenMode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
ref="autUrlInputRef"
:value="studioStore.needsUrl ? urlInProgress : autUrl"
data-cy="aut-url-input"
aria-label="url of the application under test"
class="flex grow mr-[12px] leading-normal max-w-full text-indigo-500 z-51 self-center hocus-link-default truncate"
@input="setStudioUrl"
@click="openExternally"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
>
<button
class="border rounded-md flex h-full outline-none border-gray-200 text-white transition w-[40px] duration-150 items-center justify-center hocus-default"
:aria-label="selectorPlaygroundStore.isEnabled ? 'click to interact with the application and build test cases' : 'click to exit interactive test building mode'"
data-cy="playground-toggle"
@click="toggleEnabled"
>
Expand Down Expand Up @@ -64,6 +65,7 @@
autocomplete="off"
autocorrect="off"
spellcheck="false"
aria-label="selector"
data-cy="playground-selector"
:style="{paddingLeft: leftOfInputText + 'ch', paddingRight: widthOfMatchesHelperText + 'px'}"
class="border rounded-r-md font-medium h-full outline-none border-gray-200 w-full text-indigo-500 hocus-default overflow-ellipsis"
Expand Down Expand Up @@ -103,6 +105,7 @@
variant="outline"
data-cy="playground-copy"
class="override-border"
aria-label="click to copy command to clipboard"
@click="copyToClipboard"
@focus="focus"
>
Expand All @@ -124,6 +127,7 @@
variant="outline"
data-cy="playground-print"
class="override-border"
aria-label="click to print command to console"
@click="printSelected()"
@focus="focus"
>
Expand Down
6 changes: 5 additions & 1 deletion packages/app/src/settings/device/ExternalEditorSettings.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<template>
<SettingsSection>
<template #title>
<template
id="choose-editor-label"
#title
>
{{ t('settingsPage.editor.title') }}
</template>
<template #description>
Expand All @@ -10,6 +13,7 @@
<ChooseExternalEditor
v-if="props.gql.localSettings"
:gql="props.gql"
label-id="choose-editor-label"
@chose-editor="handleChoseEditor"
/>
</SettingsSection>
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/settings/device/NotificationSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
class="py-[16px]"
>
<h4 class="flex text-gray-800 text-[16px] leading-[24px] items-center">
<label :for="id">{{ title }}</label>
<label :id="id">{{ title }}</label>
<Switch
class="mx-[8px]"
:value="props.gql.localSettings.preferences[id] ?? false"
:name="id"
:label-id="id"
:disabled="!desktopNotificationsEnabled"
@update="(value) => updatePref(id, value)"
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/settings/device/TestingPreferences.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
>
<div class="py-[16px]">
<h4 class="flex text-gray-800 text-[16px] leading-[24px] items-center">
<label :for="autoScrollingPreference.id">{{ autoScrollingPreference.title }}</label>
<label :id="autoScrollingPreference.id">{{ autoScrollingPreference.title }}</label>
<Switch
class="mx-[8px]"
:value="props.gql.localSettings.preferences[autoScrollingPreference.id] ?? false"
:name="autoScrollingPreference.id"
:label-id="autoScrollingPreference.id"
@update="(value) => updatePref(value)"
/>
</h4>
Expand Down
1 change: 1 addition & 0 deletions packages/app/src/specs/InlineRunAllSpecs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<button
class="flex h-full w-full items-center justify-center"
data-cy="run-all-specs-button"
:aria-label="t('specPage.runSelectedSpecs', specNumber)"
:disabled="specNumber === 0"
@click.stop="emits('runAllSpecs')"
>
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-shared/src/components/Input.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('<Input/>', { viewportWidth: 400, viewportHeight: 80 }, () => {
const textToType = 'My wonderful input text'

// @ts-ignore = vModel is v-model in vue
cy.mount(() => <Input vModel={value.value}/>)
cy.mount(() => <Input vModel={value.value} aria-label="status"/>)
cy.get('input').type(textToType, { delay: 0 })

cy.should(() => {
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend-shared/src/components/Select.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ const mountSelect = (props: any = {}) => {
// a click on the body dismisses the options
return cy.mount(() => (
<div class="p-12 w-[300px]">
<label id="mock-label">Mock Label</label>
<Select
options={defaultOptions}
modelValue={value}
labelId="mock-label"
{...props}
v-slots={props.vSlots}
/>
Expand Down
17 changes: 11 additions & 6 deletions packages/frontend-shared/src/components/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
@update:modelValue="handleUpdate"
>
<template #default="{ open }">
<ListboxLabel class="font-medium text-sm text-gray-800 block">
<template v-if="label">
<ListboxLabel
id="select-label"
class="font-medium text-sm text-gray-800 block"
>
<template
v-if="label"
id="labelId"
>
{{ label }}
</template>
<slot
Expand Down Expand Up @@ -72,6 +78,7 @@
leave-to-class="opacity-0"
>
<ListboxOptions
:aria-labelledby="labelId"
class="bg-white rounded shadow-lg ring-black mt-1 text-base w-full max-h-60 ring-1 ring-opacity-5 z-10 absolute overflow-auto sm:text-sm focus:outline-none"
>
<ListboxOption
Expand Down Expand Up @@ -116,7 +123,6 @@
{{ get(option, itemValue || '') }}
</slot>
</span>

<span class="flex text-sm pr-3 inset-y-0 right-0 absolute items-center">
<slot
name="item-suffix"
Expand All @@ -138,9 +144,6 @@
</span>
</div>
</ListboxOption>
<li role="option">
<slot name="footer" />
</li>
</ListboxOptions>
</transition>
</div>
Expand Down Expand Up @@ -171,6 +174,7 @@ const props = withDefaults(defineProps<{
modelValue?: Option // Current object being selected
placeholder?: string
label?: string
labelId: string
/**
* The value of the modelValue to render. `value` by default
*/
Expand All @@ -183,6 +187,7 @@ const props = withDefaults(defineProps<{
}>(), {
placeholder: '',
label: '',
labelId: undefined,
itemValue: 'value',
modelValue: undefined,
itemKey: 'key',
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend-shared/src/components/Switch.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ describe('<Switch />', () => {

cy.mount(() => (
<div class="p-6">
<label for="test-switch">Switch</label>
<label id="test-switch">Switch</label>
<Switch
// @ts-ignore
value={valueRef.value}
// @ts-ignore
onUpdate={(newVal) => (valueRef.value = newVal)}
name="test-switch"
label-id="test-switch"
/>
</div>
))
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend-shared/src/components/Switch.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<button
:id="name"
:aria-labelledby="labelId"
class="border-transparent border rounded-[50px] relative hocus-default disabled:ring-0 disabled:outline-0 disabled:bg-gray-100"
:class="[value ? 'bg-jade-400' : 'bg-gray-300', sizeClasses[size].container, {
'!hocus:ring-0': size === 'sm'
Expand All @@ -22,7 +22,7 @@
withDefaults(defineProps<{
value: boolean
size?: 'sm' | 'md' | 'lg' | 'xl'
name: string // required for an id so that an external <label> can be associated with the switch
labelId: string // required for an id so that an external <label> can be associated with the switch
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Switch component was built to be used like:

<Switch name="setting" .... />
<label for="setting">Enabled Setting</label>

Everywhere this was used was flagged with the violation buttons must have discernible text. This seems like it should be valid given it aligns with the suggested markup here.

According to dequelabs/axe-core#3696, this structure is flagged as a violation as it does not play nice with JAWS/IE 11 screen readers and axe supports those browsers.

disabled?: boolean
}>(), {
value: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ describe('ChooseExternalEditor', { viewportHeight: 400, viewportWidth: 300 }, ()
]
},
render: (gql) => {
return <div class="p-[16px]"><ChooseExternalEditor gql={gql} /></div>
return (
<div class="p-[16px]">
<label id="example-label">Mock Choose Editor</label>
<ChooseExternalEditor gql={gql} label-id="example-label" />
</div>
)
},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
:options="editorOptions"
item-value="name"
item-key="id"
:label-id="labelId"
:placeholder="t('settingsPage.editor.noEditorSelectedPlaceholder')"
class="w-[400px]"
@update:model-value="updateEditor"
Expand Down Expand Up @@ -118,6 +119,7 @@ fragment ChooseExternalEditor on Query {

const props = defineProps<{
gql: ChooseExternalEditorFragment
labelId: string
}>()

const { t } = useI18n()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<div>
<p class="font-normal text-sm text-gray-600 select-none">
<slot name="description">
<span>{{ t("globalPage.externalEditorPreferencesDescription1") }}</span>
<span id="choose-editor-label">{{ t("globalPage.externalEditorPreferencesDescription1") }}</span>
</slot>
</p>
<p class="font-normal text-sm text-gray-600 select-none">
Expand All @@ -36,6 +36,7 @@
>
<ChooseExternalEditor
:gql="props.gql"
label-id="choose-editor-label"
@chose-editor="val => preferredEditor = val ?? ''"
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@
:options="organizationOptions"
item-value="name"
item-key="id"
label-id="organization-label"
:placeholder="orgPlaceholder"
data-cy="selectOrganization"
>
<template #label>
<span class="flex font-normal my-[8px] text-[16px] leading-[24px] items-end justify-between">
<span class="">
<span
id="organization-label"
class=""
>
{{ t('runs.connect.modal.selectProject.organization') }}
</span>
<ExternalLink
Expand All @@ -76,13 +80,17 @@
:options="projectOptions"
item-value="name"
item-key="id"
label-id="project-label"
:disabled="!pickedOrganization"
:placeholder="projectPlaceholder"
data-cy="selectProject"
>
<template #label>
<div class="flex font-normal text-[16px] leading-[24px] items-center justify-between">
<p class="text-gray-800">
<p
id="project-label"
class="text-gray-800"
>
{{ t('runs.connect.modal.selectProject.project') }}
<span class="text-red-500">*</span>
</p>
Expand Down
4 changes: 2 additions & 2 deletions packages/launchpad/src/setup/ButtonBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@
class="flex px-3 items-center"
>
<label
for="altFn"
id="altFn"
class="px-3 text-gray-500"
@click="handleAlt"
>
{{ alt }}
</label>
<Switch
size="lg"
name="altFn"
label-id="altFn"
:value="altValue"
@update="handleAlt"
/>
Expand Down
3 changes: 2 additions & 1 deletion packages/launchpad/src/setup/SelectFrameworkOrBundler.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
:placeholder="props.placeholder"
:options="props.options"
item-key="id"
:label-id="props.selectorType"
@update:model-value="selectOption"
>
<template #label>
<div class="mt-[16px] mb-[8px] text-[16px] leading-[24px]">
<span>
<span :id="props.selectorType">
{{ props.label }}
</span>
<span
Expand Down
Loading