mac normalize stuff

This commit is contained in:
Joel Einbinder 2020-01-14 15:17:41 -08:00 committed by Joel Einbinder
parent 36b77efdc0
commit 9681b8bca3
2 changed files with 56 additions and 21 deletions

View file

@ -68,7 +68,7 @@ class WKAXNode implements accessibility.AXNode {
return this._children;
}
_findNeedle() : WKAXNode {
_findNeedle() : WKAXNode | null {
if (this._payload.found)
return this;
for (const child of this._children) {
@ -108,8 +108,26 @@ class WKAXNode implements accessibility.AXNode {
}
}
_isTextControl() : boolean {
switch (this._payload.role) {
case 'combobox':
case 'searchfield':
case 'textbox':
case 'TextField':
return true;
}
return false;
}
_name() : string {
if (this._payload.role === 'text')
return this._payload.value || '';
return this._payload.name || '';
}
isInteresting(insideControl: boolean) : boolean {
const {role, focusable, name} = this._payload;
const {role, focusable} = this._payload;
const name = this._name();
if (role === 'ScrollArea')
return false;
if (role === 'WebArea')
@ -129,14 +147,29 @@ class WKAXNode implements accessibility.AXNode {
return this.isLeafNode() && !!name;
}
_hasRendundantTextChild() {
if (this._children.length !== 1)
return false;
const child = this._children[0];
return child._payload.role === 'text' && this._payload.name === child._payload.value;
}
isLeafNode() : boolean {
return !this._children.length;
if (!this._children.length)
return true;
// WebKit on Linux ignores everything inside text controls, normalize this behavior
if (this._isTextControl())
return true;
// WebKit for mac has text nodes inside heading, li, menuitem, a, and p nodes
if (this._hasRendundantTextChild())
return true;
return false;
}
serialize(): accessibility.SerializedAXNode {
const node : accessibility.SerializedAXNode = {
role: WKRoleToARIARole.get(this._payload.role) || this._payload.role,
name: this._payload.name || '',
name: this._name(),
};
if ('description' in this._payload && this._payload.description !== node.name)
@ -148,13 +181,15 @@ class WKAXNode implements accessibility.AXNode {
node.roledescription = roledescription;
}
if ('value' in this._payload && this._payload.role !== 'text')
node.value = this._payload.value;
type AXPropertyOfType<Type> = {
[Key in keyof Protocol.Page.AXNode]:
Protocol.Page.AXNode[Key] extends Type ? Key : never
}[keyof Protocol.Page.AXNode];
const userStringProperties: string[] = [
'value',
'keyshortcuts',
'valuetext'
];

View file

@ -37,10 +37,6 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
<input aria-placeholder="placeholder" value="and a value" />
<div aria-hidden="true" id="desc">This is a description!</div>
<input aria-placeholder="placeholder" value="and a value" aria-describedby="desc" />
<select>
<option>First Option</option>
<option>Second Option</option>
</select>
</body>`);
// autofocus happens after a delay in chrome these days
await page.waitForFunction(() => document.activeElement.hasAttribute('autofocus'));
@ -58,10 +54,7 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
{role: 'textbox', name: '', value: 'value only'},
{role: 'textbox', name: '', value: 'and a value'}, // firefox doesn't use aria-placeholder for the name
{role: 'textbox', name: '', value: 'and a value', description: 'This is a description!'}, // and here
{role: 'combobox', name: '', value: 'First Option', haspopup: true, children: [
{role: 'combobox option', name: 'First Option', selected: true},
{role: 'combobox option', name: 'Second Option'}]
}]
]
} : CHROMIUM ? {
role: 'WebArea',
name: 'Accessibility Test',
@ -75,14 +68,12 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
{role: 'textbox', name: '', value: 'value only'},
{role: 'textbox', name: 'placeholder', value: 'and a value'},
{role: 'textbox', name: 'placeholder', value: 'and a value', description: 'This is a description!'},
{role: 'combobox', name: '', value: 'First Option', children: [
{role: 'menuitem', name: 'First Option', selected: true},
{role: 'menuitem', name: 'Second Option'}]
}]
]
} : {
role: 'WebArea',
name: 'Accessibility Test',
children: [
{role: 'text', name: 'Hello World'},
{role: 'heading', name: 'Inputs', level: 1},
{role: 'textbox', name: 'Empty input', focused: true},
{role: 'textbox', name: 'readonly input', readonly: true},
@ -91,10 +82,6 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
{role: 'textbox', name: '', value: 'value only' },
{role: 'textbox', name: 'placeholder',value: 'and a value'},
{role: 'textbox', name: 'This is a description!',value: 'and a value'}, // webkit uses the description over placeholder for the name
{role: 'button', name: '', value: 'First Option', children: [
{ role: 'MenuListOption', name: '', value: 'First Option', selected: true },
{ role: 'MenuListOption', name: '', value: 'Second Option' }]
}
]
};
expect(await page.accessibility.snapshot()).toEqual(golden);
@ -338,6 +325,19 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
await page.$eval('button', button => button.remove());
expect(await page.accessibility.snapshot({root: button})).toEqual(null);
});
it('should show uninteresting nodes', async({page}) => {
await page.setContent(`
<div id="root" role="textbox">
<div>hi</div>
</div>
`);
const root = await page.$('#root');
const snapshot = await page.accessibility.snapshot({root, interestingOnly: false});
expect(snapshot.role).toBe('textbox');
expect(snapshot.value).toBe('hi');
expect(!!snapshot.children).toBe(true);
});
});
});
function findFocusedNode(node) {