Bug 1595979 - add hittest b-c tests (general, shadowroot, zoom). Fix an e10s bug where must prune check was done on the parent side instead of deferring to childAtPoint method. r=Jamie

Differential Revision: https://phabricator.services.mozilla.com/D69823

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Yura Zenevich 2020-04-14 23:57:34 +00:00
Родитель bf4f49a410
Коммит fa747c2765
7 изменённых файлов: 290 добавлений и 5 удалений

Просмотреть файл

@ -1610,7 +1610,7 @@ mozilla::ipc::IPCResult DocAccessibleChild::RecvChildAtPoint(
*aResultDoc = nullptr;
*aResultID = 0;
Accessible* acc = IdToAccessible(aID);
if (acc && !acc->IsDefunct() && !nsAccUtils::MustPrune(acc)) {
if (acc && !acc->IsDefunct()) {
int32_t x = aX;
int32_t y = aY;
Accessible* result = acc->ChildAtPoint(

Просмотреть файл

@ -78,25 +78,25 @@ const Layout = {
x.value / dpr,
xInCSS.value,
1,
"Heights in CSS pixels is calculated correctly"
"X in CSS pixels is calculated correctly"
);
this.isWithin(
y.value / dpr,
yInCSS.value,
1,
"Heights in CSS pixels is calculated correctly"
"Y in CSS pixels is calculated correctly"
);
this.isWithin(
width.value / dpr,
widthInCSS.value,
1,
"Heights in CSS pixels is calculated correctly"
"Width in CSS pixels is calculated correctly"
);
this.isWithin(
height.value / dpr,
heightInCSS.value,
1,
"Heights in CSS pixels is calculated correctly"
"Height in CSS pixels is calculated correctly"
);
return [x.value, y.value, width.value, height.value];

Просмотреть файл

@ -4,7 +4,11 @@ support-files =
!/accessible/tests/browser/shared-head.js
!/accessible/tests/browser/*.jsm
!/accessible/tests/mochitest/*.js
!/accessible/tests/mochitest/letters.gif
[browser_test_browser.js]
[browser_test_canvas_hitregion.js]
skip-if = os == "android"
[browser_test_general.js]
[browser_test_shadowroot.js]
[browser_test_zoom.js]

Просмотреть файл

@ -0,0 +1,123 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
async function runTests(browser, accDoc) {
await waitForImageMap(browser, accDoc);
const dpr = await getContentDPR(browser);
info("Not specific case, child and deepchild testing.");
testChildAtPoint(
dpr,
3,
3,
findAccessibleChildByID(accDoc, "list"),
findAccessibleChildByID(accDoc, "listitem"),
findAccessibleChildByID(accDoc, "inner").firstChild
);
todo(
false,
"Bug 746974 - children must match on all platforms. On Windows, " +
"ChildAtPoint with eDeepestChild is incorrectly ignoring MustPrune " +
"for the graphic."
);
info(
"::MustPrune case (in this case childAtPoint doesn't look inside a " +
"textbox), point is inside of textbox."
);
const txt = findAccessibleChildByID(accDoc, "txt");
testChildAtPoint(dpr, 1, 1, txt, txt, txt);
info(
"::MustPrune case, point is outside of textbox accessible but is in document."
);
testChildAtPoint(dpr, -1, -1, txt, null, null);
info("::MustPrune case, point is outside of root accessible.");
testChildAtPoint(dpr, -10000, -10000, txt, null, null);
info("Not specific case, point is inside of btn accessible.");
const btn = findAccessibleChildByID(accDoc, "btn");
testChildAtPoint(dpr, 1, 1, btn, btn, btn);
info("Not specific case, point is outside of btn accessible.");
testChildAtPoint(dpr, -1, -1, btn, null, null);
info(
"Out of flow accessible testing, do not return out of flow accessible " +
"because it's not a child of the accessible even though visually it is."
);
await invokeContentTask(browser, [], () => {
const { CommonUtils } = ChromeUtils.import(
"chrome://mochitests/content/browser/accessible/tests/browser/Common.jsm"
);
const doc = content.document;
const rectArea = CommonUtils.getNode("area", doc).getBoundingClientRect();
const outOfFlow = CommonUtils.getNode("outofflow", doc);
outOfFlow.style.left = rectArea.left + "px";
outOfFlow.style.top = rectArea.top + "px";
});
const area = findAccessibleChildByID(accDoc, "area");
testChildAtPoint(dpr, 1, 1, area, area, area);
info("Test image maps. Their children are not in the layout tree.");
const imgmap = findAccessibleChildByID(accDoc, "imgmap");
const theLetterA = imgmap.firstChild;
await hitTest(browser, imgmap, theLetterA, theLetterA);
await hitTest(
browser,
findAccessibleChildByID(accDoc, "container"),
imgmap,
theLetterA
);
info("hit testing for element contained by zero-width element");
const container2Input = findAccessibleChildByID(accDoc, "container2_input");
await hitTest(
browser,
findAccessibleChildByID(accDoc, "container2"),
container2Input,
container2Input
);
}
addAccessibleTask(
`
<div role="list" id="list">
<div role="listitem" id="listitem"><span title="foo" id="inner">inner</span>item</div>
</div>
<span role="button">button1</span><span role="button" id="btn">button2</span>
<span role="textbox">textbox1</span><span role="textbox" id="txt">textbox2</span>
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
</div>
<div id="area" style="width: 100px; height: 100px; background-color: blue;"></div>
<map name="atoz_map">
<area id="thelettera" href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,15,15" alt="thelettera" shape="rect"/>
</map>
<div id="container">
<img id="imgmap" width="447" height="15" usemap="#atoz_map" src="http://example.com/a11y/accessible/tests/mochitest/letters.gif"/>
</div>
<div id="container2" style="width: 0px">
<input id="container2_input">
</div>
`,
runTests,
{
iframe: true,
remoteIframe: true,
// Ensure that all hittest elements are in view.
iframeAttrs: { style: "width: 600px; height: 600px;" },
}
);

Просмотреть файл

@ -0,0 +1,61 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
async function runTests(browser, accDoc) {
const dpr = await getContentDPR(browser);
let componentAcc = findAccessibleChildByID(accDoc, "component1");
testChildAtPoint(
dpr,
1,
1,
componentAcc,
componentAcc.firstChild,
componentAcc.firstChild
);
componentAcc = findAccessibleChildByID(accDoc, "component2");
testChildAtPoint(
dpr,
1,
1,
componentAcc,
componentAcc.firstChild,
componentAcc.firstChild
);
}
addAccessibleTask(
`
<div role="group" class="components" id="component1" style="display: inline-block;">
<!--
<div role="button" id="component-child"
style="width: 100px; height: 100px; background-color: pink;">
</div>
-->
</div>
<div role="group" class="components" id="component2" style="display: inline-block;">
<!--
<button>Hello world</button>
-->
</div>
<script>
// This routine adds the comment children of each 'component' to its
// shadow root.
var components = document.querySelectorAll(".components");
for (var i = 0; i < components.length; i++) {
var component = components[i];
var shadow = component.attachShadow({mode: "open"});
for (var child = component.firstChild; child; child = child.nextSibling) {
if (child.nodeType === 8)
// eslint-disable-next-line no-unsanitized/property
shadow.innerHTML = child.data;
}
}
</script>
`,
runTests,
{ iframe: true, remoteIframe: true }
);

Просмотреть файл

@ -0,0 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
async function runTests(browser, accDoc) {
if (Services.appinfo.OS !== "Darwin") {
const p1 = findAccessibleChildByID(accDoc, "p1");
const p2 = findAccessibleChildByID(accDoc, "p2");
await hitTest(browser, accDoc, p1, p1.firstChild);
await hitTest(browser, accDoc, p2, p2.firstChild);
await invokeContentTask(browser, [], () => {
const { Layout } = ChromeUtils.import(
"chrome://mochitests/content/browser/accessible/tests/browser/Layout.jsm"
);
Layout.zoomDocument(content.document, 2.0);
content.document.body.offsetTop; // getBounds doesn't flush layout on its own.
});
await hitTest(browser, accDoc, p1, p1.firstChild);
await hitTest(browser, accDoc, p2, p2.firstChild);
} else {
todo(
false,
"Bug 746974 - deepest child must be correct on all platforms, disabling on Mac!"
);
}
}
addAccessibleTask(`<p id="p1">para 1</p><p id="p2">para 2</p>`, runTests, {
iframe: true,
remoteIframe: true,
// Ensure that all hittest elements are in view.
iframeAttrs: { style: "left: 100px; top: 100px;" },
});

Просмотреть файл

@ -28,3 +28,62 @@ const { CommonUtils } = ChromeUtils.import(
const { Layout } = ChromeUtils.import(
"chrome://mochitests/content/browser/accessible/tests/browser/Layout.jsm"
);
function getChildAtPoint(container, x, y, findDeepestChild) {
try {
return findDeepestChild
? container.getDeepestChildAtPoint(x, y)
: container.getChildAtPoint(x, y);
} catch (e) {
// Failed to get child at point.
}
return null;
}
function testChildAtPoint(dpr, x, y, container, child, grandChild) {
const [containerX, containerY] = Layout.getBounds(container, dpr);
x += containerX;
y += containerY;
CommonUtils.isObject(
getChildAtPoint(container, x, y, false),
child,
`Wrong direct child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
container
)}`
);
CommonUtils.isObject(
getChildAtPoint(container, x, y, true),
grandChild,
`Wrong deepest child accessible at the point (${x}, ${y}) of ${CommonUtils.prettyName(
container
)}`
);
}
/**
* Test if getChildAtPoint returns the given child and grand child accessibles
* at coordinates of child accessible (direct and deep hit test).
*/
async function hitTest(browser, container, child, grandChild) {
const [childX, childY] = await getContentBoundsForDOMElm(
browser,
getAccessibleDOMNodeID(child)
);
const x = childX + 1;
const y = childY + 1;
CommonUtils.isObject(
getChildAtPoint(container, x, y, false),
child,
`Wrong direct child of ${prettyName(container)}`
);
CommonUtils.isObject(
getChildAtPoint(container, x, y, true),
grandChild,
`Wrong deepest child of ${prettyName(container)}`
);
}