Skip to content

Commit

Permalink
Merge pull request #5 from Igalia/cleanup-testdriver
Browse files Browse the repository at this point in the history
Clean up example
  • Loading branch information
alice authored May 30, 2024
2 parents 0dd7518 + c80d378 commit de8626e
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
<!doctype html>
<meta charset=utf-8>
<title>core-aam: acacia test using testdriver</title>
<title>core-aam: role button</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>

<body>
<div id=testtest role="button"></div>
<div id=test role=button>click me</div>

<script>
promise_test(async t => {
const node = await test_driver.get_accessibility_api_node('testtest');
assert_equals(node.role, 'push button');
}, 'An acacia test 1');
const node = await test_driver.get_accessibility_api_node('test');

// This second test is helping me find a race condition right now!
promise_test(async t => {
const node = await test_driver.get_accessibility_api_node('testtest');
assert_equals(node.role, 'push button');
}, 'An acacia test 2');
if (node.API == 'atspi') {
assert_equals(node.role, 'push button', 'Atspi role');
}
else if (node.API == 'axapi') {
assert_equals(node.role, 'AXButton', 'AX API role');
}
else {
assert_unreached(`Unknown API: ${node.API}`)
}
}, 'role button');
</script>
</body>
8 changes: 5 additions & 3 deletions resources/testdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -1076,8 +1076,10 @@
* rejected in the cases of failures.
*/
get_accessibility_api_node: async function(dom_id) {
let jsonresult = await window.test_driver_internal.get_accessibility_api_node(dom_id);
return JSON.parse(jsonresult);
return window.test_driver_internal.get_accessibility_api_node(dom_id)
.then((jsonresult) => {
return JSON.parse(jsonresult);
});
}
};

Expand Down Expand Up @@ -1269,7 +1271,7 @@
},

async get_accessibility_api_node(dom_id) {
throw new Error("not implemented, whoops!");
throw new Error("get_accessibility_api_node() is not available.");
}
};
})();
14 changes: 7 additions & 7 deletions tools/wptrunner/wptrunner/executors/executoracacia.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from .protocol import (PlatformAccessibilityProtocolPart)
from .protocol import PlatformAccessibilityProtocolPart

from sys import platform

linux = False
mac = False
if platform == "linux":
linux = True
from .executoratspi import *
linux = True
from .executoratspi import *
if platform == "darwin":
mac = True
from .executoraxapi import *
mac = True
from .executoraxapi import *


class AcaciaPlatformAccessibilityProtocolPart(PlatformAccessibilityProtocolPart):
Expand All @@ -22,6 +23,5 @@ def setup(self):
self.impl = AXAPIExecutorImpl()
self.impl.setup(self.product_name)


def get_accessibility_api_node(self, dom_id):
return self.impl.get_accessibility_api_node(dom_id)
return self.impl.get_accessibility_api_node(dom_id)
55 changes: 28 additions & 27 deletions tools/wptrunner/wptrunner/executors/executoratspi.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import gi

gi.require_version("Atspi", "2.0")
from gi.repository import Atspi
import json
import threading
from .protocol import (PlatformAccessibilityProtocolPart)


import traceback
import time
from .protocol import PlatformAccessibilityProtocolPart


def find_active_tab(root):
stack = [root]
while stack:
node = stack.pop()

if Atspi.Accessible.get_role_name(node) == 'frame':
if Atspi.Accessible.get_role_name(node) == "frame":
## Helper: list of string relations, get targets for relation?
relationset = Atspi.Accessible.get_relation_set(node)
for relation in relationset:
if relation.get_relation_type() == Atspi.RelationType.EMBEDS:
return relation.get_target(0)
if relation.get_relation_type() == Atspi.RelationType.EMBEDS:
return relation.get_target(0)
contiue

for i in range(Atspi.Accessible.get_child_count(node)):
Expand All @@ -29,24 +26,24 @@ def find_active_tab(root):

return None


def serialize_node(node):
node_dictionary = {}
node_dictionary['role'] = Atspi.Accessible.get_role_name(node)
node_dictionary['name'] = Atspi.Accessible.get_name(node)
node_dictionary['description'] = Atspi.Accessible.get_description(node)

# TODO: serialize other attributes
# states, interfaces, attributes, etc.
node_dictionary["API"] = "atspi"
node_dictionary["role"] = Atspi.Accessible.get_role_name(node)
node_dictionary["name"] = Atspi.Accessible.get_name(node)
node_dictionary["description"] = Atspi.Accessible.get_description(node)

return node_dictionary


def find_node(root, dom_id):
stack = [root]
while stack:
node = stack.pop()

attributes = Atspi.Accessible.get_attributes(node)
if 'id' in attributes and attributes['id'] == dom_id:
if "id" in attributes and attributes["id"] == dom_id:
return node

for i in range(Atspi.Accessible.get_child_count(node)):
Expand All @@ -55,6 +52,7 @@ def find_node(root, dom_id):

return None


def find_browser(name):
desktop = Atspi.get_desktop(0)
child_count = Atspi.Accessible.get_child_count(desktop)
Expand All @@ -66,52 +64,55 @@ def find_browser(name):
return (None, None)


class AtspiExecutorImpl():
class AtspiExecutorImpl:
def start_atspi_listener(self):
self._event_listener = Atspi.EventListener.new(self.handle_event)
self._event_listener.register("document:load-complete")
Atspi.event_main()


def handle_event(self, e):
app = Atspi.Accessible.get_application(e.source)
app_name = Atspi.Accessible.get_name(app)
if (self.full_app_name == app_name and e.any_data):
if self.full_app_name == app_name and e.any_data:
self.load_complete = True
self._event_listener.deregister("document:load-complete")
Atspi.event_quit()

def setup(self, product_name):
self.product_name = product_name
self.full_app_name = ''
self.full_app_name = ""
self.root = None
self.found_browser = False
self.load_complete = False

self.atspi_listener_thread = threading.Thread(target=self.start_atspi_listener)

(self.root, self.full_app_name) = find_browser(self.product_name);
(self.root, self.full_app_name) = find_browser(self.product_name)
if self.root:
self.found_browser = True
self.atspi_listener_thread.start()
else:
print(f"Cannot find root accessibility node for {self.product_name} - did you turn on accessibility?")
print(
f"Cannot find root accessibility node for {self.product_name} - did you turn on accessibility?"
)

def get_accessibility_api_node(self, dom_id):
if not self.found_browser:
return json.dumps({"role": "couldn't find browser"})
raise Exception(
f"Couldn't find browser {self.product_name}. Did you turn on accessibility?"
)

if not self.load_complete:
self.atspi_listener_thread.join()
self.atspi_listener_thread.join()

active_tab = find_active_tab(self.root)
if not active_tab:
return json.dumps({"role": "couldn't find active tab"})
raise Exception(
f"Could not find the test page within the browser. Did you turn on accessiblity?"
)

node = find_node(active_tab, dom_id)
if not node:
return json.dumps({"role": "couldn't find the node with that ID"})
raise Exception(f"Couldn't find node with id {dom_id}.")

return json.dumps(serialize_node(node))


2 changes: 1 addition & 1 deletion tools/wptrunner/wptrunner/executors/executoraxapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
kAXValueAXErrorType,
)


class AXAPIExecutorImpl:
def setup(self, product_name):
self.product_name = product_name
Expand All @@ -33,4 +34,3 @@ def get_application_by_name(self, name):

def get_accessibility_api_node(self, dom_id):
app = self.get_application_by_name(self.product_name)

0 comments on commit de8626e

Please sign in to comment.