fix(a11y): Q.DEFER.004 sub-B — AdminSupplierPricesView 9 inputs aria-label
3 supplier rows × 3 form controls (cost_rub v-text-field +
quality_score v-text-field + is_active v-switch) = 9 nodes без label —
axe-core критичная label violation.
Fix: :aria-label='${field} для ${supplier.name}' (e.g. 'Cost (₽) для B1 — Сайты и Звонки').
Test coverage: AdminSupplierPricesView.spec.ts 4-й spec проверяет все 9 ожидаемых
aria-label через DOM query.
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
density="compact"
|
||||
hide-details
|
||||
variant="plain"
|
||||
:aria-label="`Cost (₽) для ${item.name}`"
|
||||
/>
|
||||
</template>
|
||||
<template #[`item.quality_score`]="{ item }">
|
||||
@@ -24,10 +25,17 @@
|
||||
density="compact"
|
||||
hide-details
|
||||
variant="plain"
|
||||
:aria-label="`Quality для ${item.name}`"
|
||||
/>
|
||||
</template>
|
||||
<template #[`item.is_active`]="{ item }">
|
||||
<v-switch v-model="item.is_active" hide-details inset density="compact" />
|
||||
<v-switch
|
||||
v-model="item.is_active"
|
||||
hide-details
|
||||
inset
|
||||
density="compact"
|
||||
:aria-label="`Active для ${item.name}`"
|
||||
/>
|
||||
</template>
|
||||
<template #[`item.actions`]="{ item }">
|
||||
<v-btn size="small" color="primary" :loading="!!saving[item.id]" @click="save(item)">
|
||||
|
||||
@@ -58,4 +58,25 @@ describe('AdminSupplierPricesView', () => {
|
||||
const inputs = wrapper.findAll('input[type="number"]');
|
||||
expect(inputs.length).toBeGreaterThanOrEqual(6);
|
||||
});
|
||||
|
||||
it('each input/switch has explicit aria-label combining supplier name + field role', async () => {
|
||||
const wrapper = mount(AdminSupplierPricesView, { global: { plugins: [vuetify] } });
|
||||
await new Promise((r) => setTimeout(r, 50));
|
||||
// 3 suppliers × 3 fields = 9 controls
|
||||
const expectedLabels = [
|
||||
'Cost (₽) для B1 — Сайты и Звонки',
|
||||
'Quality для B1 — Сайты и Звонки',
|
||||
'Active для B1 — Сайты и Звонки',
|
||||
'Cost (₽) для B2 — SMS',
|
||||
'Quality для B2 — SMS',
|
||||
'Active для B2 — SMS',
|
||||
'Cost (₽) для B3 — SMS',
|
||||
'Quality для B3 — SMS',
|
||||
'Active для B3 — SMS',
|
||||
];
|
||||
for (const label of expectedLabels) {
|
||||
const node = wrapper.find(`[aria-label="${label}"]`);
|
||||
expect(node.exists(), `aria-label="${label}" not found`).toBe(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user