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

SIA-R8: add type="password" (and more) to applicability #1667

Merged
merged 32 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0b31288
adding failing unit test.
dan-tripp-siteimprove Aug 9, 2024
4b4afb9
adding more fialing tests.
dan-tripp-siteimprove Aug 10, 2024
d603a47
adding type="password" fields to the applicability. seems to work i.…
dan-tripp-siteimprove Aug 10, 2024
0b753b7
adding expecations Outcomes specifically for the input type="password…
dan-tripp-siteimprove Aug 10, 2024
27fbddc
- expanded applicability to include many more type="" attribute value…
dan-tripp-siteimprove Aug 13, 2024
f755a89
changeset.
dan-tripp-siteimprove Aug 27, 2024
2ce7ffe
changeset.
dan-tripp-siteimprove Aug 27, 2024
31c2a8e
Update packages/alfa-rules/src/sia-r8/rule.ts
dan-tripp-siteimprove Aug 30, 2024
983ecbd
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
a5f4959
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
c99988d
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
6c2a0a0
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
4cea3b7
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
a68a0c1
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
a1e18f5
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
159d693
fixing recently-introduced compilation error, I think.
dan-tripp-siteimprove Aug 30, 2024
b8c3fa1
fixing recently-introduced error in test.
dan-tripp-siteimprove Aug 30, 2024
f5aac10
changing import style as per review advice at https://github.com/Site…
dan-tripp-siteimprove Aug 30, 2024
7adf7cf
tightening up the types by using the same InputType type that hasInpu…
dan-tripp-siteimprove Aug 30, 2024
c0848bf
removing unused import.
dan-tripp-siteimprove Aug 30, 2024
af35fbc
Update packages/alfa-rules/test/sia-r8/rule.spec.tsx
dan-tripp-siteimprove Aug 30, 2024
861baeb
making new experimental rule: sia-er8.
dan-tripp-siteimprove Aug 30, 2024
dfc2719
changeset.
dan-tripp-siteimprove Aug 30, 2024
cedb192
refactoring as per review comment at https://github.com/Siteimprove/a…
dan-tripp-siteimprove Aug 31, 2024
7a40ee5
Extract API
github-actions[bot] Sep 2, 2024
d543582
Merge branch 'main' into r8-password-field
Jym77 Sep 2, 2024
5ee3fc1
Update .changeset/swift-meals-check.md
dan-tripp-siteimprove Sep 16, 2024
8b65244
Update packages/alfa-rules/src/experimental.ts
dan-tripp-siteimprove Sep 16, 2024
9b6bda3
Update packages/alfa-rules/src/sia-er8/rule.ts
dan-tripp-siteimprove Sep 16, 2024
64a9731
Update packages/alfa-rules/src/sia-er8/rule.ts
dan-tripp-siteimprove Sep 16, 2024
8613e4a
minor fixes - consequent to the review at https://github.com/Siteimpr…
dan-tripp-siteimprove Sep 16, 2024
f37faf4
Extract API
github-actions[bot] Sep 17, 2024
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
5 changes: 5 additions & 0 deletions .changeset/swift-meals-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@siteimprove/alfa-rules": minor
---

**Added:** Experimental rule SIA-ER8. It adds support for type="password" and more.
8 changes: 5 additions & 3 deletions docs/review/api/alfa-dom.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ export namespace Element {
// @internal (undocumented)
export function fromElement<N extends string = string>(json: JSON<N>, device?: Device): Trampoline<Element<N>>;
// (undocumented)
export type InputType = helpers.InputType;
// (undocumented)
export function isElement(value: unknown): value is Element;
// (undocumented)
export interface JSON<N extends string = string> extends Node.JSON<"element"> {
Expand All @@ -362,9 +364,6 @@ export namespace Element {
// (undocumented)
style: Block.JSON | string | null;
}
// (undocumented)
export interface MinimalJSON extends Node.JSON<"element"> {
}
const // Warning: (ae-forgotten-export) The symbol "predicate_3" needs to be exported by the entry point index.d.ts
//
// (undocumented)
Expand All @@ -391,6 +390,9 @@ export namespace Element {
//
// (undocumented)
inputType: typeof helpers.inputType;
// (undocumented)
export interface MinimalJSON extends Node.JSON<"element"> {
}
}

// @public (undocumented)
Expand Down
42 changes: 23 additions & 19 deletions docs/review/api/alfa-rules.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,44 @@ import { Text } from '@siteimprove/alfa-dom';
// @public (undocumented)
export const alfaVersion = "0.89.3";

// @public (undocumented)
const _default: Rule.Atomic<Page, Element<string>, {}, Element<string>>;

// @public @deprecated (undocumented)
const _default_10: Rule.Atomic<Page, Text, Question.Metadata, Text>;

// @public
const _default: Rule.Atomic<Page, Document, Question.Metadata, Element<string>>;
const _default_2: Rule.Atomic<Page, Document, Question.Metadata, Element<string>>;

// @public
const _default_2: Rule.Atomic<Page, Element<string>, Question.Metadata, Node<string> | Array_2<Node<string>>>;
const _default_3: Rule.Atomic<Page, Element<string>, Question.Metadata, Node<string> | Array_2<Node<string>>>;

// @public
const _default_3: Rule.Atomic<Page, Document, Question.Metadata, Document>;
const _default_4: Rule.Atomic<Page, Document, Question.Metadata, Document>;

// @public @deprecated (undocumented)
const _default_4: Rule.Atomic<Page, Element<string>, {}, Element<string>>;
const _default_5: Rule.Atomic<Page, Element<string>, {}, Element<string>>;

// @public @deprecated (undocumented)
const _default_5: Rule.Atomic<Page, Attribute<string>, {}, Attribute<string>>;

// @public (undocumented)
const _default_6: Rule.Atomic<Page, Element<string>, Question.Metadata, Element<string>>;
const _default_6: Rule.Atomic<Page, Attribute<string>, {}, Attribute<string>>;

// @public (undocumented)
const _default_7: Rule.Atomic<Page, Element<string>, Question.Metadata, Element<string>>;

// @public @deprecated (undocumented)
const _default_8: Rule.Atomic<Page, Text, Question.Metadata, Text>;
// @public (undocumented)
const _default_8: Rule.Atomic<Page, Element<string>, Question.Metadata, Element<string>>;

// @public @deprecated (undocumented)
const _default_9: Rule.Atomic<Page, Text, Question.Metadata, Text>;

declare namespace deprecatedRules {
export {
_default_4 as DR6,
_default_5 as DR18,
_default_6 as DR34,
_default_7 as DR36,
_default_8 as DR66,
_default_9 as DR69
_default_5 as DR6,
_default_6 as DR18,
_default_7 as DR34,
_default_8 as DR36,
_default_9 as DR66,
_default_10 as DR69
}
}
export { deprecatedRules }
Expand Down Expand Up @@ -93,9 +96,10 @@ export namespace Diagnostic {

declare namespace experimentalRules {
export {
_default as ER87,
_default_2 as R82,
_default_3 as R109
_default as ER8,
_default_2 as ER87,
_default_3 as R82,
_default_4 as R109
}
}
export { experimentalRules }
Expand Down
2 changes: 2 additions & 0 deletions packages/alfa-dom/src/node/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -573,4 +573,6 @@ export namespace Element {
} = predicate;

export const { inputType } = helpers;

export type InputType = helpers.InputType;
}
3 changes: 2 additions & 1 deletion packages/alfa-rules/src/experimental.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ER8 from "./sia-er8/rule.js";
import ER87 from "./sia-er87/rule.js";

import R82 from "./sia-r82/rule.js";
import R109 from "./sia-r109/rule.js";

export { ER87, R82, R109 };
export { ER8, ER87, R82, R109 };
96 changes: 96 additions & 0 deletions packages/alfa-rules/src/sia-er8/rule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { Diagnostic, Rule } from "@siteimprove/alfa-act";
import type { Role } from "@siteimprove/alfa-aria";
import * as aria from "@siteimprove/alfa-aria"
import { Element, Namespace, Node, Query } from "@siteimprove/alfa-dom";
import { Predicate } from "@siteimprove/alfa-predicate";
import { Err, Ok } from "@siteimprove/alfa-result";
import { Criterion } from "@siteimprove/alfa-wcag";
import type { Page } from "@siteimprove/alfa-web";

import { expectation } from "../common/act/expectation.js";

import { Scope, Stability, Version } from "../tags/index.js";
import { WithRole } from "../common/diagnostic.js";

const { hasNonEmptyAccessibleName, hasRole, isIncludedInTheAccessibilityTree } = aria.DOM;
const { hasInputType, hasNamespace } = Element;
const { and, or } = Predicate;
const { getElementDescendants } = Query;

export default Rule.Atomic.of<Page, Element>({
uri: "https://alfa.siteimprove.com/rules/sia-r8",
requirements: [Criterion.of("4.1.2")],
tags: [Scope.Component, Stability.Experimental, Version.of(2)],
evaluate({ device, document }) {
return {
applicability() {
return getElementDescendants(document, Node.fullTree).filter(
and(
hasNamespace(Namespace.HTML),
or(
hasRole(
device,
"checkbox",
"combobox",
"listbox",
"menuitemcheckbox",
"menuitemradio",
"radio",
"searchbox",
"slider",
"spinbutton",
"switch",
"textbox",
),
hasInputType("password", "color", "date", "datetime-local", "file", "month", "time", "week"),
),
isIncludedInTheAccessibilityTree(device),
),
);
},

expectations(target) {
const role = aria.Node.from(target, device).role;
if(role.isSome()) {
const roleName = role.get().name;
return {
1: expectation(
hasNonEmptyAccessibleName(device)(target),
() => Outcomes.FormFieldWithAriaRoleHasName(roleName),
() => Outcomes.FormFieldWithAriaRoleHasNoName(roleName),
),
};
} else {
// We know the type attribute has a correct value because of the applicability.
const inputType = target.attribute("type").map(attr => attr.value).getUnsafe(`R8v2 found an element with no role nor 'type' attribute: ${target.path()}`) as Element.InputType;
return {
1: expectation(
hasNonEmptyAccessibleName(device)(target),
() => Outcomes.InputElementWithNoAriaRoleHasName(inputType),
() => Outcomes.InputElementWithNoAriaRoleHasNoName(inputType),
),
};
}
},
};
},
});

/**
* @public
*/
export namespace Outcomes {
export const FormFieldWithAriaRoleHasName = (role: Role.Name) =>
Ok.of(WithRole.of(`The form field has an accessible name`, role));

export const FormFieldWithAriaRoleHasNoName = (role: Role.Name) =>
Err.of(
WithRole.of(`The form field does not have an accessible name`, role),
);

export const InputElementWithNoAriaRoleHasName = (typeAttribValue: Element.InputType) =>
Ok.of(Diagnostic.of(`The type="${typeAttribValue}" form field has an accessible name`));

export const InputElementWithNoAriaRoleHasNoName = (typeAttribValue: Element.InputType) =>
Err.of(Diagnostic.of(`The type="${typeAttribValue}" form field does not have an accessible name`));
}
1 change: 1 addition & 0 deletions packages/alfa-rules/src/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"./sia-dr36/rule.ts",
"./sia-dr66/rule.ts",
"./sia-dr69/rule.ts",
"./sia-er8/rule.ts",
"./sia-er87/rule.ts",
"./sia-r1/rule.ts",
"./sia-r10/rule.ts",
Expand Down
Loading