mac normalize stuff
This commit is contained in:
parent
36b77efdc0
commit
9681b8bca3
|
|
@ -68,7 +68,7 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
return this._children;
|
return this._children;
|
||||||
}
|
}
|
||||||
|
|
||||||
_findNeedle() : WKAXNode {
|
_findNeedle() : WKAXNode | null {
|
||||||
if (this._payload.found)
|
if (this._payload.found)
|
||||||
return this;
|
return this;
|
||||||
for (const child of this._children) {
|
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 {
|
isInteresting(insideControl: boolean) : boolean {
|
||||||
const {role, focusable, name} = this._payload;
|
const {role, focusable} = this._payload;
|
||||||
|
const name = this._name();
|
||||||
if (role === 'ScrollArea')
|
if (role === 'ScrollArea')
|
||||||
return false;
|
return false;
|
||||||
if (role === 'WebArea')
|
if (role === 'WebArea')
|
||||||
|
|
@ -129,14 +147,29 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
return this.isLeafNode() && !!name;
|
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 {
|
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 {
|
serialize(): accessibility.SerializedAXNode {
|
||||||
const node : accessibility.SerializedAXNode = {
|
const node : accessibility.SerializedAXNode = {
|
||||||
role: WKRoleToARIARole.get(this._payload.role) || this._payload.role,
|
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)
|
if ('description' in this._payload && this._payload.description !== node.name)
|
||||||
|
|
@ -148,13 +181,15 @@ class WKAXNode implements accessibility.AXNode {
|
||||||
node.roledescription = roledescription;
|
node.roledescription = roledescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('value' in this._payload && this._payload.role !== 'text')
|
||||||
|
node.value = this._payload.value;
|
||||||
|
|
||||||
type AXPropertyOfType<Type> = {
|
type AXPropertyOfType<Type> = {
|
||||||
[Key in keyof Protocol.Page.AXNode]:
|
[Key in keyof Protocol.Page.AXNode]:
|
||||||
Protocol.Page.AXNode[Key] extends Type ? Key : never
|
Protocol.Page.AXNode[Key] extends Type ? Key : never
|
||||||
}[keyof Protocol.Page.AXNode];
|
}[keyof Protocol.Page.AXNode];
|
||||||
|
|
||||||
const userStringProperties: string[] = [
|
const userStringProperties: string[] = [
|
||||||
'value',
|
|
||||||
'keyshortcuts',
|
'keyshortcuts',
|
||||||
'valuetext'
|
'valuetext'
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,6 @@ module.exports.describe = function({testRunner, expect, FFOX, CHROMIUM, WEBKIT})
|
||||||
<input aria-placeholder="placeholder" value="and a value" />
|
<input aria-placeholder="placeholder" value="and a value" />
|
||||||
<div aria-hidden="true" id="desc">This is a description!</div>
|
<div aria-hidden="true" id="desc">This is a description!</div>
|
||||||
<input aria-placeholder="placeholder" value="and a value" aria-describedby="desc" />
|
<input aria-placeholder="placeholder" value="and a value" aria-describedby="desc" />
|
||||||
<select>
|
|
||||||
<option>First Option</option>
|
|
||||||
<option>Second Option</option>
|
|
||||||
</select>
|
|
||||||
</body>`);
|
</body>`);
|
||||||
// autofocus happens after a delay in chrome these days
|
// autofocus happens after a delay in chrome these days
|
||||||
await page.waitForFunction(() => document.activeElement.hasAttribute('autofocus'));
|
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: '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'}, // firefox doesn't use aria-placeholder for the name
|
||||||
{role: 'textbox', name: '', value: 'and a value', description: 'This is a description!'}, // and here
|
{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 ? {
|
} : CHROMIUM ? {
|
||||||
role: 'WebArea',
|
role: 'WebArea',
|
||||||
name: 'Accessibility Test',
|
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: '', value: 'value only'},
|
||||||
{role: 'textbox', name: 'placeholder', value: 'and a value'},
|
{role: 'textbox', name: 'placeholder', value: 'and a value'},
|
||||||
{role: 'textbox', name: 'placeholder', value: 'and a value', description: 'This is a description!'},
|
{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',
|
role: 'WebArea',
|
||||||
name: 'Accessibility Test',
|
name: 'Accessibility Test',
|
||||||
children: [
|
children: [
|
||||||
|
{role: 'text', name: 'Hello World'},
|
||||||
{role: 'heading', name: 'Inputs', level: 1},
|
{role: 'heading', name: 'Inputs', level: 1},
|
||||||
{role: 'textbox', name: 'Empty input', focused: true},
|
{role: 'textbox', name: 'Empty input', focused: true},
|
||||||
{role: 'textbox', name: 'readonly input', readonly: 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: '', value: 'value only' },
|
||||||
{role: 'textbox', name: 'placeholder',value: 'and a value'},
|
{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: '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);
|
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());
|
await page.$eval('button', button => button.remove());
|
||||||
expect(await page.accessibility.snapshot({root: button})).toEqual(null);
|
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) {
|
function findFocusedNode(node) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue