cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.07k stars 3.19k forks source link

Improve Specs List Markup #22811

Open marktnoonan opened 2 years ago

marktnoonan commented 2 years ago

What would you like?

The markup for the specs list should better reflect the nature and structure of the content it displays. Functionally, this list includes a combination of many different different behaviors and kinds of content, some of which are not expressed correctly to be accessible to assistive technology and keyboard users. Here are the current features of the specs list:

  1. Table-like headings and columns
  2. Expandable/collapsible tree view of directories
  3. Clickable "spec" rows that link to open each spec in the spec runner
  4. The rows themselves contain table-like data about the spec name, git status (last updated), latest runs, and average spec duration, identified by the headings at the top of the page.
  5. The "git status" data has a tooltip providing more details (commit message, committer, etc)
  6. The "latest runs" data has a tooltip that contains 9 pieces of information and is itself a clickable link to visit the dashboard.

This is challenging from an accessibility perspective, and though it's probably impossible to be perfect, it can be much more functional than it is now.

Currently

The specs list is currently structured as a flat sequence of elements, and each element represents either a directory or a spec "row" in the list.

Directory rows are button elements and they are used to expand/contract the contents that belong to that directory. Spec rows are anchor elements and they link the user to the Spec Runner for the given spec. The entire contents of the row are combined and announced as the label to this link. Keyboard users can tab to the internal elements and see the tooltips, though not interact with the clickable one.

Theses rows also represent the directory tree, though this tree is not represented in the DOM directly: the visual effect of a tree is created by indentation with CSS padding.

Some improvements

(All of these would be made with no visual change in the UI)

The specs within a directory represent tabular data, so we should render a table to contain spec rows. The table should identify the column headers, and the table's caption should identify the path of the current directory.

This would allow assistive technology to correctly associate the headers with the data in the table the same way we visually associate them in the UI. This seems like it might need to nested tables, which would not be great, but in reality there is no nesting of components here, as mentioned above - the effect of nesting is created by padding applied with CSS. So to replicate the visual nesting effect when the page is being described, we use the table's caption.

As for the content tooltips, the existing tooltip structure should mostly work as is. Since the individual cells would be exposed to screen readers, and no longer get clobbered by the whole thing being wrapped in an a tag, the individual aria-labelledby content should be announced. We'll want to test and make sure, but tooltips would probably be changed very lightly, if at all, by this work.

Changes needed to support tables in this part of the app

We will need to process the flat data a little so that groups of "spec" rows are gathered into single items that can be passed to a new component to render the table and its rows. That new table component can take care of all the required table markup. Directories would continue to be rendered just as they are and visual nesting would work as it does now.

Click events on non-interactive parts of the row would need to be captured appropriately to navigate to the chosen spec in the runner.

Benefits of doing this

Users of assistive technology will have a much clearer understanding of where they are in this deeply nested content structure, and the semantic table elements will allow traditional navigation and announcing of cell contents, headings, etc. to do the heavy lifting. It will take real users to confirm if this is the most usable approach to the problem, but it is certainly an improvement.

For developers: the rows are already pretty heavily and are likely to be extended further. Pulling them into a semantically-appropriate structure will make it easier to understand what's going on when reading the code, and easier to extend with new functionality in the future. Plus all new columns or data will be extensions of an already-correct setup which avoids us reinventing the the wheel for what is essentially a combination of known patterns.

This will also remove the logic and named slots SpecsListRowItem.vue, since all of that exists to create a tabular layout. Instead of passing contents into slots we can use <tr> and <td> elements directly, and SpecsListRowItem will only be used to render directories, and it can then be combined with the RowDirectory component, removing a layer of abstraction.

It's possible we would want to wrap the table in a component, but it wouldn't actually be much different to what we have now to just use a table directly.

Why is this needed?

No response

Other

No response

github-actions[bot] commented 1 year ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.

marktnoonan commented 1 year ago

We should keep this issue open for now. We can close it if we address the issues directly or if a future iteration of the specs list removes these issues entirely.