-
Notifications
You must be signed in to change notification settings - Fork 13
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
Update SIA R67 #272
Update SIA R67 #272
Changes from all commits
f637df8
ed73fc5
fb31519
85ede53
ccf9789
e4d5099
780ed5f
e9a327d
0173101
05c1cd7
f1a8350
0a0ad3c
65e4b15
6b02e20
a0c3267
cc37cae
f271e89
b0c5440
564ee73
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import {Node} from "@siteimprove/alfa-aria"; | ||
import {getName} from "@siteimprove/alfa-aria/src/get-name"; | ||
import { Device } from "@siteimprove/alfa-device"; | ||
import { jsx } from "@siteimprove/alfa-dom/jsx"; | ||
import { Option } from "@siteimprove/alfa-option"; | ||
import { Predicate } from "@siteimprove/alfa-predicate"; | ||
import { test } from "@siteimprove/alfa-test"; | ||
|
||
import { Document, Element } from "@siteimprove/alfa-dom"; | ||
|
||
import R67, { Outcomes } from "../../src/sia-r67/rule"; | ||
|
||
import { evaluate } from "../common/evaluate"; | ||
import { passed, failed, inapplicable } from "../common/outcome"; | ||
|
||
const { and } = Predicate; | ||
const { hasId } = Element; | ||
|
||
const device = Device.standard(); | ||
|
||
function getElementById(document: Document): (id: string) => Element { | ||
return (id) => | ||
document | ||
.descendants() | ||
.find(and(Element.isElement, hasId(id))) | ||
.get(); | ||
} | ||
|
||
test("evaluate() passes on elements marked as decorative and not exposed", async (t) => { | ||
const document = Document.of((self) => [ | ||
Element.fromElement( | ||
<html> | ||
<img id="empty-alt" src="foo.jpg" alt="" /> | ||
<img id="role-none" src="foo.jpg" role="none" /> | ||
<img id="role-presentation" src="foo.jpg" role="presentation" /> | ||
<svg id="svg" role="none"> | ||
<circle cx="50" cy="50" r="40" fill="yellow"></circle> | ||
</svg> | ||
<img id="aria-hidden" src="foo.jpg" role="none" aria-hidden="true" /> | ||
<div aria-hidden="true"><img id="aria-hidden-inherit" src="foo.jpg" role="none" /></div> | ||
</html>, | ||
Option.of(self) | ||
), | ||
]); | ||
const getById = getElementById(document); | ||
const emptyAlt = getById("empty-alt"); | ||
const roleNone = getById("role-none"); | ||
const rolePresentation = getById("role-presentation"); | ||
const svg = getById("svg"); | ||
Comment on lines
+46
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be done using destructuring and without additional helpers and need for IDs: const [img, video, object, svg] = document
.first()
.get()
.children()
.filter(Element.isElement); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, but this is less resilient to changes in the HTML. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's reasonable 👍 What we need then is a unified approach to this rather than ad-hoc helpers scattered throughout rule spec files. Test code is most annoying code to maintain so it needs to be super maintainable 🙈 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I totally agree. If we decide that IDs + getter is the way we wanna go, we should of course make the helper common and update existing tests to use it… There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #281 should hopefully help on the last point. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah it gets a bit better. Still need to Document.fromDocument(
h.document([
<html>
<head>
<title>Hello world</title>
</head>
</html>
])
); instead of documentFromHtml(<html>
<head>
<title>Hello world</title>
</head>
</html>); |
||
const ariaHidden = getById("aria-hidden"); | ||
const ariaHiddenInherit = getById("aria-hidden-inherit"); | ||
|
||
t.deepEqual(await evaluate(R67, { device, document }), [ | ||
passed(R67, emptyAlt, { 1: Outcomes.IsNotExposed }), | ||
passed(R67, roleNone, { 1: Outcomes.IsNotExposed }), | ||
passed(R67, rolePresentation, { 1: Outcomes.IsNotExposed }), | ||
passed(R67, svg, { 1: Outcomes.IsNotExposed }), | ||
passed(R67, ariaHidden, { 1: Outcomes.IsNotExposed }), | ||
passed(R67, ariaHiddenInherit, { 1: Outcomes.IsNotExposed }), | ||
]); | ||
}); | ||
|
||
test("evaluate() fails on elements marked as decorative but exposed", async (t) => { | ||
const document = Document.of((self) => [ | ||
Element.fromElement( | ||
<html> | ||
<span id="label">Foo</span> | ||
<img id="empty-alt-aria-label" src="foo.jpg" alt="" aria-label="Foo" /> | ||
<img | ||
id="role-none-aria-labelledby" | ||
src="foo.jpg" | ||
role="none" | ||
aria-labelledby="label" | ||
/> | ||
</html>, | ||
Option.of(self) | ||
), | ||
]); | ||
const getById = getElementById(document); | ||
const emptyAltAriaLabel = getById("empty-alt-aria-label"); | ||
const roleNoneAriaLabelledby = getById("role-none-aria-labelledby"); | ||
|
||
t.deepEqual(await evaluate(R67, { device, document }), [ | ||
failed(R67, emptyAltAriaLabel, { 1: Outcomes.IsExposed }), | ||
failed(R67, roleNoneAriaLabelledby, { 1: Outcomes.IsExposed }), | ||
]); | ||
}); | ||
|
||
test("evaluate() is inapplicable on non-img/svg elements", async (t) => { | ||
const document = Document.of((self) => [ | ||
Element.fromElement( | ||
<html> | ||
<math role="none"></math> | ||
<span role="none"></span> | ||
<iframe role="presentation"></iframe> | ||
</html>, | ||
Option.of(self) | ||
), | ||
]); | ||
|
||
t.deepEqual(await evaluate(R67, { device, document }), [inapplicable(R67)]); | ||
}); | ||
|
||
test("evaluate() is inapplicabale on elements which are not marked as decorative", async (t) => { | ||
const document = Document.of((self) => [ | ||
Element.fromElement( | ||
<html> | ||
<img src="foo.jpg" alt="foo" /> | ||
<img src="foo.jpg" /> | ||
<img src="foo.jpg" /> | ||
<svg> | ||
<circle cx="50" cy="50" r="40" fill="yellow"></circle> | ||
</svg> | ||
</html>, | ||
Option.of(self) | ||
), | ||
]); | ||
|
||
t.deepEqual(await evaluate(R67, { device, document }), [inapplicable(R67)]); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🙈