Description
In investigating a way to specify layout tables (see #562), I came to the realisation that browsers are very inconsistent in the way they expose a layout table. Parking the heuristics for a second, I actually mean their computed role.
Consider the document at URL data:text/html,<!DOCTYPE%20html><table><td>
. This is consistently produces a "layout table" in all browsers.
Using test_driver.get_computed_role(el)
where el
is considered to be a "layout table" returns different results depending on the browser and the platform (again, ignoring heuristics).
- Firefox will always compute the role as
"table"
. It has a separate accessible attributelayout_guess
which will betrue
if it considers the table to be a layout table, which will either be omitted if the table is a data table. Rows/Cells/Columns do not get thislayout_guess
attribute. This is passed as thelayout-guess: true
attribute on IA2/ATK. - Chrome will compute the role as
"LayoutTable"
for tables it deems as layout tables, and"table"
for tables deems to be data tables - EXCEPT on Windows and ChromeOS where it will always compute the role as"table"
. When a table is a"LayoutTable"
the computed roles for columns will be"LayoutTableColumn"
, cells"LayoutTableCell"
, and rows"LayoutTableRow"
. These roles map to different roles on different platforms:- On macos all layout tables and their rows/cells map to
NSAccessibilityGroupRole
(read: "group"). Data tables map toNSAcessbilityTableRole
, rows & cols to their respective roles. - On UIA layout tables, and their constituent rows/cells/columns will map will to
"group"
, but thelayout-guess: true
attribute will be passed. - ATK will map layout tables to
ATK_ROLE_SECTION
(read: generic).layout-guess: true
will be passed as an attribute.
- On macos all layout tables and their rows/cells map to
- WebKit (tested both Safari on macos and Gnome Web on Linux) will compute the role as
""
for tables it deems are layout tables, and"table"
for tables it deems are data tables. Rows/Cells/Columns will compute as""
when the table is a layout table.
There are several conclusions I draw here:
- Chrome has mappings that we could reasonably specify.
- All browsers do something different on macos it seems?
- 2 browsers will expose layout tables as not
"table"
at least some of the time. - Chrome is exposing a completely non-standard set of roles (
"LayoutTable"
and co). - Either way, at least 1 browser will need to change what it does.
I think we can do 2 things here:
1. Ensure computed role must return "table"
We could reasonably specify that the computed role should be "table". Each of the mappings can perform a bit of logic to determine what roles/attributes are actually sent to APIs.
Pros:
- That's currently the behaviour that Firefox exhibits, meaning only 2 browsers need to change.
- No new roles!
Cons:
- It makes this difficult to test, as the computed role would always be "table".
- To make it easier to test, this means all browsers will need to do some work, perhaps expose accessible attributes to WebDriver?
- WebKit & Chrome do not currently comply with this, so would need to change.
- There's probably a good reason why WebKit acts like it does.
2. We could specify "layouttable"/"layouttablerow"/"layouttablecell" as ARIA roles, which can then have their own mapping.
Pros:
- The mappings are kept relatively isolated, only
<table>
's computed role would need to change, and then everything would fall out from there (the mappings for thelayout-*
roles would need to be created, but that's quite straightforward). - It would be much easier to test; no changes would need to happen in web driver.
- Changes in Chrome would be quite minimal, likely just renaming the
"Layout*
roles to all lower case.
Cons: - All three browsers would need some level of change, work in Firefox would be the most significant.
- This gives validity to a broken pattern which we likely want to discourage.