Skip to content

Commit

Permalink
chore(rules): add img ignore alt empty title [H67]
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mendez committed Oct 22, 2023
1 parent 37ea0d6 commit 778f344
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ let audit = accessibility_rs::audit(&AuditConfig::new(&html, &css, false, "en"))
### Features

1. Accurate web accessibility WCAG audits.
1. Re-creating layout trees to get element positions without the DOM.
1. Ideal shapes for audits that scale.
1. Shortest path css selectors for elements.
1. Incredibly fast nanosecond audits.
1. i18n support.
1. Ideal shapes for audits that scale.
1. Shortest path CSS selectors for elements.
1. i18n support for multiple languages.
1. Re-creating layout tree to get element position coordinates.

## Benchmarks

Expand Down
5 changes: 3 additions & 2 deletions RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion accessibility-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "accessibility-rs"
version = "0.0.40"
version = "0.0.41"
authors = ["The A11yWatch Project Developers", "Jeff Mendez <jeff@a11ywatch.com>"]
edition = "2021"
license = "MIT OR Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion accessibility-rs/src/engine/issue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions accessibility-rs/src/engine/rules/techniques.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub enum Techniques {
H63,
/// <https://www.w3.org/TR/WCAG20-TECHS/H64>
H64,
/// <https://www.w3.org/TR/WCAG20-TECHS/H67>
H67,
/// <https://www.w3.org/TR/WCAG20-TECHS/H71>
H71,
/// <https://www.w3.org/TR/WCAG20-TECHS/H91>
Expand Down
18 changes: 17 additions & 1 deletion accessibility-rs/src/engine/rules/utils/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,30 @@ 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,
_ => false,
}
}

/// 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<String>) {
let mut valid = true;
Expand Down
17 changes: 16 additions & 1 deletion accessibility-rs/src/engine/rules/wcag_rule_map.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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| {
Expand Down
25 changes: 25 additions & 0 deletions accessibility-rs/tests/unit/img.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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###"<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>Contains Title with Alt: Do not Use.</title>
</head>
<body>
<img src="newsletter.gif" alt="" title="empty newsletter"/>
</body>
</html>"###,
));
let mut valid = true;

for x in &audit {
if x.code == "WCAGAAA.Principle1.Guideline1_1.H67" {
valid = false;
break;
}
}

assert_eq!(valid, false)
}
2 changes: 1 addition & 1 deletion accessibility-rs/tests/unit/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion accessibility-rs/tests/unit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit 778f344

Please sign in to comment.