From c946ce85020abf26de84860389b6263dd3ea98cc Mon Sep 17 00:00:00 2001 From: Bill Dengler Date: Tue, 31 Oct 2023 14:32:28 -0700 Subject: [PATCH] feat(wcag-2-2): Add "dragging movements" test (#7058) This commit adds "dragging movements" to the assessment experience. Part of Feature 2100304 (internal access required to view). Co-authored-by: Madalyn <3230904+madalynrose@users.noreply.github.com> --- src/assessments/pointer-motion/assessment.tsx | 9 +- .../test-steps/dragging-movements.tsx | 60 +++++ .../pointer-motion/test-steps/test-steps.ts | 1 + .../pointer-motion/dragging-movements.tsx | 89 ++++++++ src/content/test/pointer-motion/index.ts | 2 + .../guidance-content.test.ts.snap | 208 ++++++++++++++++++ 6 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 src/assessments/pointer-motion/test-steps/dragging-movements.tsx create mode 100644 src/content/test/pointer-motion/dragging-movements.tsx diff --git a/src/assessments/pointer-motion/assessment.tsx b/src/assessments/pointer-motion/assessment.tsx index 046471a8cf0..7c0946ef2d1 100644 --- a/src/assessments/pointer-motion/assessment.tsx +++ b/src/assessments/pointer-motion/assessment.tsx @@ -6,6 +6,7 @@ import * as React from 'react'; import { AssessmentBuilder } from '../assessment-builder'; import { Assessment } from '../types/iassessment'; +import { DraggingMovements } from './test-steps/dragging-movements'; import { MotionOperation } from './test-steps/motion-operation'; import { PointerCancellation } from './test-steps/pointer-cancellation'; import { PointerGestures } from './test-steps/pointer-gestures'; @@ -30,5 +31,11 @@ export const PointerMotionAssessment: Assessment = AssessmentBuilder.Assisted({ gettingStarted: gettingStarted, guidance, visualizationType: VisualizationType.PointerMotionAssessment, - requirements: [PointerGestures, PointerCancellation, MotionOperation, TargetSize], + requirements: [ + PointerGestures, + PointerCancellation, + MotionOperation, + DraggingMovements, + TargetSize, + ], }); diff --git a/src/assessments/pointer-motion/test-steps/dragging-movements.tsx b/src/assessments/pointer-motion/test-steps/dragging-movements.tsx new file mode 100644 index 00000000000..e79f1bf33d1 --- /dev/null +++ b/src/assessments/pointer-motion/test-steps/dragging-movements.tsx @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +import { NewTabLink } from 'common/components/new-tab-link'; +import { link } from 'content/link'; +import * as content from 'content/test/pointer-motion/dragging-movements'; +import * as React from 'react'; + +import { ManualTestRecordYourResults } from '../../common/manual-test-record-your-results'; +import { Requirement } from '../../types/requirement'; +import { PointerMotionTestStep } from './test-steps'; + +const description: JSX.Element = ( + + The action of dragging cannot be the only means available to perform an action, with + exceptions on where dragging is essential to the functionality, or the dragging mechanism is + not built by the web author (e.g., native browser functionality unmodified by the author). + +); + +const howToTest: JSX.Element = ( +
+
    +
  1. +

    + Examine the target page to identify elements that support dragging (such as + press and hold, repositioning of pointer, releasing the pointer at end point). +

    +
  2. +
  3. +

    + Verify that there is an{' '} + + single pointer + {' '} + activation alternative that does not require dragging to operate the same + function +

    +

    + Exception: This criterion does not apply to scrolling enabled by the user-agent. + Scrolling a page is not in scope, nor is using a technique such as CSS overflow + to make a section of content scrollable. This criterion also applies to web + content that interprets pointer actions (i.e. this does not apply to actions + that are required to operate the user agent or assistive technology). +

    +
  4. + +
+
+); + +export const DraggingMovements: Requirement = { + key: PointerMotionTestStep.draggingMovements, + name: 'Dragging movements', + description, + howToTest, + ...content, + isManual: true, + guidanceLinks: [link.WCAG_2_5_7], +}; diff --git a/src/assessments/pointer-motion/test-steps/test-steps.ts b/src/assessments/pointer-motion/test-steps/test-steps.ts index 422e6ccdced..6cba79a9cdb 100644 --- a/src/assessments/pointer-motion/test-steps/test-steps.ts +++ b/src/assessments/pointer-motion/test-steps/test-steps.ts @@ -4,5 +4,6 @@ export const enum PointerMotionTestStep { pointerGestures = 'pointer-gestures', pointerCancellation = 'pointer-cancellation', motionOperation = 'motion-operation', + draggingMovements = 'dragging-movements', targetSize = 'target-size', } diff --git a/src/content/test/pointer-motion/dragging-movements.tsx b/src/content/test/pointer-motion/dragging-movements.tsx new file mode 100644 index 00000000000..da500f23d0d --- /dev/null +++ b/src/content/test/pointer-motion/dragging-movements.tsx @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +import { create, React } from '../../common'; + +export const infoAndExamples = create(({ Markup }) => ( + <> +

+ The action of dragging cannot be the only means available to perform an action, with exceptions on where dragging is essential + to the functionality, or the dragging mechanism is not built by the web author (e.g., native browser functionality unmodified by + the author). +

+

Why it matters

+

Users who struggle with performing dragging movements need to still operate an interface with a pointer interface.

+

+ Some people cannot perform dragging movements in a precise manner. Others use a specialized or adapted input device, such as a + trackball, head pointer, eye-gaze system, or speech-controlled mouse emulator, which may make dragging cumbersome and + error-prone. When an interface implements functionality that uses dragging movements, users perform discrete actions such as + tapping or clicking to establish a starting point or press and hold that contact. Not all users can accurately press and hold + that contact while also repositioning the pointer. An alternative method must be provided so that users with mobility + impairments who use a pointer (mouse, pen, or touch contact) can use the functionality. +

+ +

How to fix

+

+ For any function that can be operated through dragging, make sure that the user can (1) operate the function through dragging, + or (2) there is a single pointer{' '} + activation (for example single taps, clicks) alternative that does not require dragging to operate the same function. +

+ +

Example

+ + A table’s columns can only be resized if someone can use a mouse to click on the column divider and then drag it to a + new position, adjusting the width of the column in the process. +

+ } + passText={ + <> +

+ To pass this instance, an alternative "move" button could be provided, where if pressed, the next mouse click on + another area of the UI could result in the table column adjustments without the need to specifically drag the column + divider there. +

+

+ Another way to pass this instance would be to provide alternative controls to adjust the width, such as with menus, + buttons, or text fields to adjust the value. These alternative methods would allow someone to click or press + different controls to adjust the table columns, without having to drag or use keyboard commands which may be + difficult to perform (e.g., rapidly pressing, or long-pressing different keys). +

+ + } + /> + +

More examples

+

WCAG success criteria

+ + + Understanding Success Criterion 2.5.7: Dragging Movements + + +

Sufficient techniques

+ + + G219: Ensuring that an alternative is available for dragging movements that operate on content + + + Failure of Success Criterion 2.5.7 Dragging Movements due to not providing a single pointer method for the user to operate a + function that does not require a dragging movement + + +

Additional guidance

+ + + Understanding Success Criterion 2.5.1: Pointer Gestures + + + Providing single point activation for a control slider + + + Failure of Success Criterion 2.5.1 due to providing functionality via a path-based gesture without simple pointer + alternative + + + Providing controls to achieve the same result as path based or multipoint gestures + + + +)); diff --git a/src/content/test/pointer-motion/index.ts b/src/content/test/pointer-motion/index.ts index 23c67f07f2a..7af74f3491f 100644 --- a/src/content/test/pointer-motion/index.ts +++ b/src/content/test/pointer-motion/index.ts @@ -1,5 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import * as draggingMovements from './dragging-movements'; import { guidance } from './guidance'; import * as motionOperation from './motion-operation'; import * as pointerCancellation from './pointer-cancellation'; @@ -11,5 +12,6 @@ export const pointerMotion = { pointerCancellation, pointerGestures, motionOperation, + draggingMovements, targetSize, }; diff --git a/src/tests/end-to-end/tests/content/__snapshots__/guidance-content.test.ts.snap b/src/tests/end-to-end/tests/content/__snapshots__/guidance-content.test.ts.snap index 53c0bc32dbd..b8b52e73713 100644 --- a/src/tests/end-to-end/tests/content/__snapshots__/guidance-content.test.ts.snap +++ b/src/tests/end-to-end/tests/content/__snapshots__/guidance-content.test.ts.snap @@ -26125,6 +26125,214 @@ exports[`Guidance Content pages test/parsing/parsingContent/infoAndExamples matc `; +exports[`Guidance Content pages test/pointerMotion/draggingMovements/infoAndExamples matches the snapshot 1`] = ` + +
+
+
+

+ The action of dragging cannot be the only means available to perform an action, with exceptions on where dragging is essential to the functionality, or the dragging mechanism is not built by the web author (e.g., native browser functionality unmodified by the author). +

+

+ Why it matters +

+

+ Users who struggle with performing dragging movements need to still operate an interface with a pointer interface. +

+

+ Some people cannot perform dragging movements in a precise manner. Others use a specialized or adapted input device, such as a trackball, head pointer, eye-gaze system, or speech-controlled mouse emulator, which may make dragging cumbersome and error-prone. When an interface implements functionality that uses dragging movements, users perform discrete actions such as tapping or clicking to establish a starting point or press and hold that contact. Not all users can accurately press and hold that contact while also repositioning the pointer. An alternative method must be provided so that users with mobility impairments who use a pointer (mouse, pen, or touch contact) can use the functionality. +

+

+ How to fix +

+

+ For any function that can be operated through dragging, make sure that the user can (1) operate the function through dragging, or (2) there is a + + single pointer + + activation (for example single taps, clicks) alternative that does not require dragging to operate the same function. +

+

+ Example +

+
+
+
+ + + + +

+ Fail +

+
+

+ A table’s columns can only be resized if someone can use a mouse to click on the column divider and then drag it to a new position, adjusting the width of the column in the process. +

+
+
+
+ + + + +

+ Pass +

+
+

+ To pass this instance, an alternative "move" button could be provided, where if pressed, the next mouse click on another area of the UI could result in the table column adjustments without the need to specifically drag the column divider there. +

+

+ Another way to pass this instance would be to provide alternative controls to adjust the width, such as with menus, buttons, or text fields to adjust the value. These alternative methods would allow someone to click or press different controls to adjust the table columns, without having to drag or use keyboard commands which may be difficult to perform (e.g., rapidly pressing, or long-pressing different keys). +

+
+
+

+ More examples +

+

+ WCAG success criteria +

+ +

+ Sufficient techniques +

+ +

+ Additional guidance +

+ +
+
+
+ +`; + exports[`Guidance Content pages test/pointerMotion/guidance matches the snapshot 1`] = `