Skip to content

Commit

Permalink
Develop branch (#771)
Browse files Browse the repository at this point in the history
* SIA R3: add test (#792)
* SIA R4: test added (#793)
* SIA R5: add test (#794)
* R6 test added (#795)
* SIA-R8: Added tests (#806)
* Add basic tests for R11 (#770)
* SIA R12: Add Test (#800)
* SIA R17: add test (#791)
* R18 add test (#803)
* SIA-R19: Add test (#807)
* Test for SIA-R20 added
* Add tests for R42

* Remove second expectation from R62 (#772)
* SIA R62: accept different font weight (#779)

* Implement pseudo classes equality (#773)
* Add equals() and toString() to functional pseudo-classes and elements

* Name computation: skip step 1 when descending (#778)
* Accessible name: reject whitespace descendants (#831)

* Extended diagnostic for R14 (#786)
* R16 extended diagnostic (#804)
* R62 extended diagnostic (#801)

* Fix background-size (#788)
* Support text-decoration-thickness (#817)
* Support `font-variant` CSS property (#821)

* Assume no background on size (#789)

* Fix hasRole to pick the role from the accessible node (#805)

* Increase Nodejs heap size (#818)

* SIA R65: accept different border as focus indicator (#819)

* Implement SIA R56 (#829)

Co-authored-by: elenamongelli <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Kasper Isager <[email protected]>
  • Loading branch information
4 people authored Jun 14, 2021
1 parent 32ca8f3 commit bfb1a0d
Show file tree
Hide file tree
Showing 124 changed files with 4,559 additions and 731 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/integrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ jobs:
name: Build
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
os: [ ubuntu-latest, windows-latest ]
node: [12, 14]
runs-on: ${{ matrix.os }}
env:
NODE_OPTIONS: "--max-old-space-size=4096"
steps:
- uses: actions/[email protected]
- uses: actions/[email protected]
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ As new code is pulled from the repository, changes to dependencies and code may
$ yarn build
```

If you want to run tests and make sure everything is working, use:

```console
$ yarn test
```

When working on a specific package, you can run only these tests:

```console
$ yarn test packages/alfa-<package-name>
```

If you would like to contribute to Alfa, make sure to check out the [contribution guidelines](docs/contributing.md). If you have any questions, you are also welcome to [open an issue][].

## Architecture
Expand Down
10 changes: 8 additions & 2 deletions packages/alfa-aria/src/name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,13 @@ export namespace Name {
// https://w3c.github.io/accname/#step1
// Step 1 is skipped when referencing due to step 2B.ii.b
// https://w3c.github.io/accname/#step2B.ii.b
if (!state.isReferencing && role.some((role) => role.isNameProhibited())) {
// Step 1 is skipped when descending due to step 2F.iii.b
// https://w3c.github.io/accname/#step2B.iii.b
if (
!state.isReferencing &&
!state.isDescending &&
role.some((role) => role.isNameProhibited())
) {
return None;
}

Expand Down Expand Up @@ -736,7 +742,7 @@ export namespace Name {
)
);

const name = flatten(names.map((name) => name.value).join(" "));
const name = flatten(names.map((name) => name.value).join(" ")).trim();

if (name === "") {
return None;
Expand Down
101 changes: 101 additions & 0 deletions packages/alfa-aria/test/name.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,27 @@ test(`.from() determines the name of an <a> element with a <img> child element
});
});

test(`.from() rejects whitespace only content and defaults to next step`, (t) => {
const a = (
<a href="#" title="Hello world">
<span> </span>
</a>
);

t.deepEqual(Name.from(a, device).toJSON(), {
type: "some",
value: {
value: "Hello world",
sources: [
{
type: "label",
attribute: "/a[1]/@title",
},
],
},
});
});

test(`.from() determines the name of an <a> element with a <figure> child element
with a <img> child element with an alt attribute`, (t) => {
const a = (
Expand Down Expand Up @@ -473,6 +494,86 @@ test(`.from() determines the name of an <a> element with text in its subtree,
});
});

test(`.from() determines the name of an <a> element with text in its subtree,
when the source is nested and doesn't itself allow naming`, (t) => {
const a = (
<a href="#" title="Content">
<p>Hello world</p>
</a>
);

t.deepEqual(Name.from(a, device).toJSON(), {
type: "some",
value: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]",
name: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]/p[1]",
name: {
value: "Hello world",
sources: [
{
type: "data",
text: "/a[1]/p[1]/text()[1]",
},
],
},
},
],
},
},
],
},
});
});

test(`.from() determines the name of an <a> element with text in its subtree,
when the source is nested and presentational`, (t) => {
const a = (
<a href="#" title="Content">
<span role="none">Hello world</span>
</a>
);

t.deepEqual(Name.from(a, device).toJSON(), {
type: "some",
value: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]",
name: {
value: "Hello world",
sources: [
{
type: "descendant",
element: "/a[1]/span[1]",
name: {
value: "Hello world",
sources: [
{
type: "data",
text: "/a[1]/span[1]/text()[1]",
},
],
},
},
],
},
},
],
},
});
});

test(`.from() determines the name of an <a> element with text in its subtree,
when there are multiple nested sources`, (t) => {
const a = (
Expand Down
6 changes: 6 additions & 0 deletions packages/alfa-css/src/syntax/nth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ export class Nth implements Iterable<Token>, Equatable, Serializable {
offset: this._offset,
};
}

public toString(): string {
return this._step === 0
? `${this._offset}`
: `${this._step}n+${this._offset};`;
}
}

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/alfa-rules/src/common/expectation/get-colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ function getLayers(
return None;
}

// If there is a background-size, we currently have no way of guessing
// whether it is large enough to go under the text or not.
// So we simply bail out.
if (
!style
.computed("background-size")
.value.equals(style.initial("background-size").value)
) {
return None;
}

// For each gradient, we extract all color stops into a background layer of
// their own. As gradients need a start and an end point, there will always
// be at least two color stops.
Expand Down
4 changes: 2 additions & 2 deletions packages/alfa-rules/src/common/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export class Group<T>
return new Group(Array.from(members));
}

private readonly _members: Array<T>;
private readonly _members: ReadonlyArray<T>;

private constructor(members: Array<T>) {
private constructor(members: ReadonlyArray<T>) {
this._members = members;
}

Expand Down
3 changes: 3 additions & 0 deletions packages/alfa-rules/src/common/normalize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function normalize(input: string): string {
return input.trim().toLowerCase().replace(/\s+/g, " ");
}
3 changes: 0 additions & 3 deletions packages/alfa-rules/src/common/predicate/has-border.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ export function hasBorder(
return sides.some(
(side) =>
style.computed(`border-${side}-width` as const).none(Length.isZero) &&
style
.computed(`border-${side}-style` as const)
.none((style) => style.value === "none") &&
style
.computed(`border-${side}-color` as const)
.none((color) => color.type === "color" && Color.isTransparent(color))
Expand Down
12 changes: 9 additions & 3 deletions packages/alfa-rules/src/common/predicate/has-role.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { Role } from "@siteimprove/alfa-aria";
import { Node, Role } from "@siteimprove/alfa-aria";
import { Device } from "@siteimprove/alfa-device";
import { Element } from "@siteimprove/alfa-dom";
import { Predicate } from "@siteimprove/alfa-predicate";

export function hasRole(predicate?: Predicate<Role>): Predicate<Element>;
export function hasRole(
device: Device,
predicate?: Predicate<Role>
): Predicate<Element>;

export function hasRole<N extends Role.Name>(
device: Device,
name: N,
...rest: Array<N>
): Predicate<Element>;

export function hasRole(
device: Device,
nameOrPredicate: Predicate<Role> | Role.Name = () => true,
...names: Array<Role.Name>
): Predicate<Element> {
Expand All @@ -21,5 +27,5 @@ export function hasRole(
predicate = Role.hasName(nameOrPredicate, ...names);
}

return (element) => Role.from(element).some(predicate);
return (element) => Node.from(element, device).role.some(predicate);
}
8 changes: 4 additions & 4 deletions packages/alfa-rules/src/common/predicate/is-tabbable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ const { and, not } = Predicate;
export function isTabbable(device: Device): Predicate<Element> {
return and(
hasTabIndex((tabIndex) => tabIndex >= 0),
and(
not(redirectsFocus),
and(not(isDisabled), not(isInert(device)), isRendered(device))
)
not(redirectsFocus),
not(isDisabled),
not(isInert(device)),
isRendered(device)
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-rules/src/sia-r10/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default Rule.Atomic.of<Page, Attribute>({
hasAttribute("autocomplete", hasTokens),
or(
isTabbable(device),
hasRole((role) => role.isWidget())
hasRole(device, (role) => role.isWidget())
),
isPerceivable(device),
(element) =>
Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-rules/src/sia-r11/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default Rule.Atomic.of<Page, Element>({
.filter(
and(
hasNamespace(Namespace.HTML),
hasRole("link"),
hasRole(device, "link"),
not(isIgnored(device))
)
);
Expand Down
2 changes: 1 addition & 1 deletion packages/alfa-rules/src/sia-r12/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default Rule.Atomic.of<Page, Element>({
and(
not(hasInputType("image")),
hasNamespace(Namespace.HTML),
hasRole("button"),
hasRole(device, "button"),
not(isIgnored(device))
)
);
Expand Down
Loading

0 comments on commit bfb1a0d

Please sign in to comment.