From 4d3b7dcb389d94b33800efc939f31b1a26e67e6c Mon Sep 17 00:00:00 2001 From: j-mendez Date: Sat, 21 Oct 2023 21:49:02 -0400 Subject: [PATCH] chore(rules): add img ignore alt empty title [H67] --- Cargo.lock | 2 +- RULES.md | 5 ++-- accessibility-rs/Cargo.toml | 2 +- accessibility-rs/src/engine/issue.rs | 2 +- .../src/engine/rules/techniques.rs | 2 ++ .../src/engine/rules/utils/nodes.rs | 18 ++++++++++++- .../src/engine/rules/wcag_rule_map.rs | 17 ++++++++++++- accessibility-rs/tests/unit/img.rs | 25 +++++++++++++++++++ accessibility-rs/tests/unit/label.rs | 2 +- accessibility-rs/tests/unit/mod.rs | 2 +- 10 files changed, 68 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5efb7ca..f205c0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "accessibility-rs" -version = "0.0.40" +version = "0.0.41" dependencies = [ "accessibility-scraper", "accessibility-tree", diff --git a/RULES.md b/RULES.md index 7ebe0d7..1b58f9c 100644 --- a/RULES.md +++ b/RULES.md @@ -20,16 +20,17 @@ List of [WCAG2.1 techniques](https://www.w3.org/TR/WCAG21/) and whether or not w | [H57](https://www.w3.org/TR/WCAG20-TECHS/H57.html) | lang attribute of the document element does not appear to be well-formed | A-AAA | error | 3.Lang | ✅ | | [H57](https://www.w3.org/TR/WCAG20-TECHS/H57.html) | xml:lang attribute of the document element does not appear to be well-formed | A-AAA | error | 3.XmlLang | ✅ | | [H64](https://www.w3.org/TR/WCAG20-TECHS/H64.html) | iframe missing title attribute | A-AAA | error | 1 | ✅ | +| [H67](https://www.w3.org/TR/WCAG20-TECHS/H67.html) | Img element with empty alt text must have absent or empty title attribute | A-AAA | error | 1 | ✅ | | [H71](https://www.w3.org/TR/WCAG20-TECHS/H71.html) | fieldset missing legend element | A-AAA | error | 2 | ✅ | | [H91](https://www.w3.org/TR/WCAG20-TECHS/H91.html) | anchor valid href attribute, but no link content | A-AAA | error | A.NoContent | ✅ | | [H91](https://www.w3.org/TR/WCAG20-TECHS/H91.html) | anchor found but no link content | A-AAA | error | A.EmptyNoId | ✅ | | [H91](https://www.w3.org/TR/WCAG20-TECHS/H91.html) | form control needs name | A-AAA | error | [NodeName].Name | ✔️ | -| [H93](https://www.w3.org/TR/WCAG20-TECHS/H93.html) | label has multiple for ids | A-AAA | error | | ✅ | +| [H93](https://www.w3.org/TR/WCAG20-TECHS/H93.html) | label has multiple for ids | A-AAA | error | | ✅ | | [F40](https://www.w3.org/TR/WCAG20-TECHS/F40.html) | meta redirect used with a time limit | A-AAA | error | 2 | ✅ | | [F41](https://www.w3.org/TR/WCAG20-TECHS/F41.html) | meta refresh used to reload the page | A-AAA | error | 2 | ✅ | | [F47](https://www.w3.org/TR/WCAG20-TECHS/F47.html) | blink element used for attention | A-AAA | error | | ✅ | | [F77](https://www.w3.org/TR/WCAG20-TECHS/F77.html) | duplicate ID found | A-AAA | error | | ✅ | -Errors that can be to be tested with automation `23/70`. +Errors that can be to be tested with automation `24/70`. Key: ✅ = Complete, ✔️ = Complete with a bit of missing details. diff --git a/accessibility-rs/Cargo.toml b/accessibility-rs/Cargo.toml index da102cc..1ea4b85 100644 --- a/accessibility-rs/Cargo.toml +++ b/accessibility-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "accessibility-rs" -version = "0.0.40" +version = "0.0.41" authors = ["The A11yWatch Project Developers", "Jeff Mendez "] edition = "2021" license = "MIT OR Apache-2.0" diff --git a/accessibility-rs/src/engine/issue.rs b/accessibility-rs/src/engine/issue.rs index 94ace6b..9feb4ea 100644 --- a/accessibility-rs/src/engine/issue.rs +++ b/accessibility-rs/src/engine/issue.rs @@ -61,7 +61,7 @@ impl Issue { Issue { message, context: context.into(), - runner: "kayle", + runner: "accessibility-rs", code: code.into(), issue_type, type_code: match issue_type { diff --git a/accessibility-rs/src/engine/rules/techniques.rs b/accessibility-rs/src/engine/rules/techniques.rs index 9b2fcb7..6a41dc8 100644 --- a/accessibility-rs/src/engine/rules/techniques.rs +++ b/accessibility-rs/src/engine/rules/techniques.rs @@ -27,6 +27,8 @@ pub enum Techniques { H63, /// H64, + /// + H67, /// H71, /// diff --git a/accessibility-rs/src/engine/rules/utils/nodes.rs b/accessibility-rs/src/engine/rules/utils/nodes.rs index 2409114..a466149 100644 --- a/accessibility-rs/src/engine/rules/utils/nodes.rs +++ b/accessibility-rs/src/engine/rules/utils/nodes.rs @@ -19,7 +19,7 @@ pub fn has_alt(ele: ElementRef<'_>) -> bool { has_alt_prop(ele) } -/// a valid alt attribute for image +/// a valid attribute for element pub fn has_alt_prop(ele: ElementRef<'_>) -> bool { match ele.attr("alt") { Some(_) => true, @@ -27,6 +27,22 @@ pub fn has_alt_prop(ele: ElementRef<'_>) -> bool { } } +/// property found for element +pub fn has_prop(ele: ElementRef<'_>, prop: &str) -> bool { + match ele.attr(prop) { + Some(_) => true, + _ => false, + } +} + +/// property found for element and is not empty +pub fn has_prop_value(ele: ElementRef<'_>, prop: &str) -> bool { + match ele.attr(prop) { + Some(p) => !p.is_empty(), + _ => false, + } +} + /// elements empty pub fn is_empty(nodes: &ElementNodes) -> (bool, Vec) { let mut valid = true; diff --git a/accessibility-rs/src/engine/rules/wcag_rule_map.rs b/accessibility-rs/src/engine/rules/wcag_rule_map.rs index c2876e7..4a18094 100644 --- a/accessibility-rs/src/engine/rules/wcag_rule_map.rs +++ b/accessibility-rs/src/engine/rules/wcag_rule_map.rs @@ -1,7 +1,8 @@ use crate::engine::rules::rule::{Rule, Validation}; use crate::engine::rules::techniques::Techniques; use crate::engine::rules::utils::nodes::{ - get_unique_selector, has_alt, has_alt_prop, validate_empty_nodes, validate_missing_attr, + get_unique_selector, has_alt, has_alt_prop, has_prop, has_prop_value, validate_empty_nodes, + validate_missing_attr, }; use crate::engine::rules::wcag_base::{Guideline, IssueType, Principle}; use crate::i18n::locales::get_message_i18n_str_raw; @@ -256,6 +257,20 @@ lazy_static! { Validation::new(valid, "", elements, Default::default()).into() }), + Rule::new(Techniques::H67.into(), IssueType::Error, Principle::Perceivable, Guideline::TextAlternatives, "1", |nodes, _lang| { + let mut valid = true; + let mut elements = Vec::new(); + + for ele in nodes { + let ele = ele.0; + if has_prop(ele, "alt") && has_prop_value(ele, "title") { + valid = false; + elements.push(get_unique_selector(&ele)) + } + } + + Validation::new(valid, "1", elements, Default::default()).into() + }), ])), ("h1", Vec::from([ Rule::new(Techniques::H42.into(), IssueType::Error, Principle::Perceivable, Guideline::Adaptable, "1", |nodes, _lang| { diff --git a/accessibility-rs/tests/unit/img.rs b/accessibility-rs/tests/unit/img.rs index 5d65201..cf51436 100644 --- a/accessibility-rs/tests/unit/img.rs +++ b/accessibility-rs/tests/unit/img.rs @@ -53,3 +53,28 @@ fn _audit_form_submit_img_missing_alt() { assert_eq!(valid, false) } + +#[test] +/// img has empty alt and title +fn _audit_form_submit_img_has_alt_and_title() { + let audit = accessibility_rs::audit(AuditConfig::basic( + r###" + + Contains Title with Alt: Do not Use. + + + + + "###, + )); + let mut valid = true; + + for x in &audit { + if x.code == "WCAGAAA.Principle1.Guideline1_1.H67" { + valid = false; + break; + } + } + + assert_eq!(valid, false) +} diff --git a/accessibility-rs/tests/unit/label.rs b/accessibility-rs/tests/unit/label.rs index 1ec74b5..d4a86f6 100644 --- a/accessibility-rs/tests/unit/label.rs +++ b/accessibility-rs/tests/unit/label.rs @@ -29,7 +29,7 @@ fn _audit_label_id_noexist() { }; let audit = accessibility_rs::audit(AuditConfig::basic(&markup.into_string())); - + let valid = !audit .iter() .any(|x| x.code == "WCAGAAA.Principle1.Guideline1_3.H44"); diff --git a/accessibility-rs/tests/unit/mod.rs b/accessibility-rs/tests/unit/mod.rs index 5cb3273..5dd938b 100644 --- a/accessibility-rs/tests/unit/mod.rs +++ b/accessibility-rs/tests/unit/mod.rs @@ -5,5 +5,5 @@ pub mod heading; pub mod html; pub mod img; pub mod input; +pub mod label; pub mod meta; -pub mod label; \ No newline at end of file