Coder Social home page Coder Social logo

telenium's Introduction

Telenium

Telenium provide a framework to remote tests or automation Kivy-based application:

  • Selector support using XPATH-like syntax (//BoxLayout[0]/Button[@text~="Close"])
  • Create selector by touching the UI
  • Query or set attribute on any widgets
  • Execute remote code
  • unittests support
  • Integrate as a Kivy modules
  • Web IDE
  • Python 2 and 3 (since version 0.4, using json-rpc)

Telenium IDE

Telenium IDE export

Installation

pip install telenium

Run the Telenium IDE

It will start a webserver on http://127.0.0.1:8080/ and automatically open a new tab in your favorite webbrowser. You'll be able to configure where your main.py is, and start writing tests directly:

telenium

You can also edit telenium-json:

telenium tests/test-ui-myfeature.json

Run the application with telenium module

If you don't use the IDE, in order to remote control your application, you need the Telenium client installed within your application.

Method 1: Run your application with telenium client

Telenium can execute your application and manually add telenium_client to it. Just do:

python -m telenium.execute main.py

Method 2: Import and install telenium client in your application

Telenium client can be imported and installed at the start of your application:

If telenium is fully available:

from telenium import install
install()

If you only included telenium_client.py module:

from telenium_client import install
install()

Method 3: Add telenium_client as a Kivy modules into your application

Just copy/paste mods/telenium_client.py in your application, then before running your application, initialize it:

from os.path import dirname
from kivy.modules import Modules
from kivy.config import Config
Modules.add_path(dirname(__file__))
Config.set("modules", "telenium_client", "")

You also need to add python-jsonrpc in your dependencies (pip install python-jsonrpc)

Remote automation

You can easily create a script that will connect to your telenium client, and do stuff.

import telenium
cli = telenium.connect()

# wait until the SaveCSVButton instance is in the widget tree.
cli.wait_click("//SaveCSVButton")
# wait that one label have Export to CSV text
cli.wait("//Label[@text~=\"Export to CSV\"]", timeout=2)
# make a screenshot !
result = cli.screenshot()
print(result["filename"])
print(result["data"])

Connect to a telenium-ready application

We have a command line client to play with. After the application is started, you can connect with::

$ python -m telenium.client localhost

Then play with it. cli is the telenium client where you can invoke remote commands. See the Telenium commands to see what you can do:

>>> id = cli.pick() # then click somewhere on the UI
>>> cli.click_at(id)
True
>>> cli.setattr("//Label", "color", (0, 1, 0, 1))
True

If a command returns True, it means it has been successful, otherwise it returns None.

Create unit tests

Telenium have a module you can use that ease unit tests: it launch the app and execute tests. For now, it has been tested and coded to work only locally using subprocess.

Additionnal methods:

  • assertExists(selector, timeout=-1) and assertNotExists(selector, timeout=-1) to check if a selector exists or not in the app. They both have a timeout parameter that, if it reach, will fail the test.
  • cli.wait_click(selector, timeout=-1): easy way to wait a selector to match, then click on the first widget.

Here is a real example that launch an app (default is "main.py"):

  • It first go in the menu to click where it need to save a CSV (SaveButton, CascadeSaveButton then SaveCSVButton)
  • Then wait at maximum 2s the popup to show with a label "Export to CSV"
  • Then click on the "Close" button in the popup
  • Then ensure the popup is closed by checking the label is gone.

Example:

from telenium.tests import TeleniumTestCase

class UITestCase(TeleniumTestCase):
    cmd_entrypoint = ["main.py"]

    def test_export_csv(self):
        self.cli.wait_click("//SaveButton")
        self.cli.wait_click("//CascadeSaveButton")
        self.cli.wait_click("//SaveCSVButton")
        self.assertExists("//Label[@text~=\"Export to CSV\"]", timeout=2)
        self.cli.wait_click("//FitButton[@text=\"Close\"]", timeout=2)
        self.assertNotExists("//Label[@text~=\"Export to CSV\"]", timeout=2)

Each new TeleniumTestCase will close and start the application, so you always run from a clean app. If you always need to do something before starting the test, you can overload the init. This will be executed once before any tests in the class starts:

class UITestCase(TeleniumTestCase):
    def init(self):
        self.cli.wait_click("//PresetSelectionItem[@text!~=\"ttyUSB0 on mintel\"]",
                           timeout=10)
        self.cli.wait_click("//Button[@text=\"Connect\"]")
        self.cli.wait("//BottomLabel[@text=\"Done\"]", timeout=10)

You can also change few parameters to change/add things in your application for unit testing if needed:

class UITestCase(TeleniumTestCase):
    process_start_timeout = 5
    cmd_env = {"I_AM_RUNNING_TEST": 1}

Telenium commands

version()

Return the current API version. You can use it to know which methods are available.

>>> cli.version()
1

select(selector)

Return unique selectors for all widgets that matches the selector.

>>> cli.select("//Label")
[u"/WindowSDL/GridLayout/Label[0]", u"/WindowSDL/GridLayout/Label[1]"]

getattr(selector, key)

Return the value of an attribute on the first widget found by the selector.

>>> cli.getattr("//Label", "text")
u"Hello world"

setattr(selector, key, value)

Set an attribute named by key to value for all widgets that matches the selector.

>>> cli.setattr("//Label", "text", "Plop")
True

element(selector)

Return True if at least one widget match the selector.

>>> cli.element("//Label")
True
>>> cli.element("//InvalidButton")
False

execute(code)

Execute python code in the application. Only the "app" symbol that point to the current running application is available. Return True if the code executed, or False if the code failed. Exception will be print withing the application logs.

>>> cli.execute("app.call_one_app_method")
True

pick(all=False)

Return either the first widget selector you touch on the screen (all=False, the default), either it return the list of all the wigdets that are traversed where you touch the screen.

>>> cli.pick()
u'/WindowSDL/Button[0]'
>>> cli.pick(all=True)
[u'/WindowSDL/Button[0]',u'/WindowSDL']

click_on(selector)

Simulate a touch down/up on the first widget that match the selector. Return True if it worked.

>>> cli.click_on("//Button[0]")
True

screenshot(filename=None) (>= 0.5.0)

Take a screenshot of the current application in a PNG format. Data will be saved into filename if passed, or you can have data in the result.

>>> cli.screenshot("hello.png")
{"filename": "hello.png", "data": "base64 utf-8 encoded data..."}

evaluate(expr) (>= 0.5.0)

Evaluate an expression, and return the result. Only serializable result can be fetched, if an object is sent back, you'll receive None.

>>> cli.evaluate("len(app.my_list)")
123

evaluate_and_store(key, expr) (>= 0.5.0)

Evaluate an expression, and store the result in a id-map, used by execute and evaluate method.

>>> cli.evaluate_and_store("root", "app.root.children[0]")
True
>>> cli.execute("root.do_something()")

select_and_store(key, selector) (>= 0.5.0)

Select the first widget returned by a selector, and store the result in a id-map, used by execute and evaluate method.

>>> cli.select_and_store("btn", "//Button[@title~='Login']")
True
>>> cli.execute("btn.disabled = True")

Telenium selector syntax (XPATH)

Cheat sheet about telenium XPATH-based selector implementation.

  • Select any widget that match the widget class in the hierarchy: //CLASS
  • Select a widget that match the tree: /CLASS
  • Select a widget with attributes /CLASS[<ATTR SELECTOR>,...]
  • Index selector if there is multiple match: /CLASS[INDEX]
  • Attribute exists: @attr
  • Attribute equal to a value: @attr=VALUE
  • Attribute not equal to a value: @attr!=VALUE
  • Attribute contain a value: @attr~=VALUE
  • Attribute does not contain a value: @attr!~=VALUE
  • Value can be a string, but must be escaped within double quote only.

Some examples:

# Select all the boxlayout in the app
//BoxLayout

# Take the first boxlayout
//BoxLayout[0]

# Get the Button as a direct descendant of the BoxLayout
//BoxLayout[0]/Button

# Or get the 5th Button that are anywhere under the BoxLayout (may or may
# not a direct descandant)
//BoxLayout[0]//Button

# Select the button that is written "Close"
//BoxLayout[0]//Button[@text="Close"]

# Select the button that contain "Close"
//BoxLayout[0]//Button[@text~="Close"]

Real life examples

Automate screenshots of an app

I was having an app where content is displayed randomly. But the client want to review all the texts and position of every content. Easy peasy::

from telenium import connect
prefix = "screenshots/myapp-"

cli = connect()
cli.wait("//MyAppContainer")
cli.select_and_store("root", "//MyAppContainer")

animals_count = cli.evaluate("len(root.animals)")
for index in range(animals_count):
    # get one animal
    cli.evaluate_and_store("animal", f"root.animals[{index}]")
    animal_id = cli.evaluate("animal['id']")
    animal_name = cli.evaluate("animal['title_en']")
    # focus the animal
    cli.execute("root.focus_animal(animal)")
    cli.sleep(3)
    # take a screenshot
    cli.screenshot(f"{prefix}{animal_id}-{animal_name}.png")
    cli.sleep(3)

Automate login and go directly to the right screen

If you code, close your app, restart, login, do many action before reaching the screen you are currently working on, you could automate the first part.

from telenium import connect
cli = connect()
cli.wait('//IntroUI')
cli.execute("app.username = 'username'")
cli.execute("app.userpwd = 'fake'")
cli.click_on('//LoginButton')
cli.wait('//IntroUI')
cli.click_on('//StartButton')
cli.wait('//GameUI')

telenium's People

Contributors

andremiras avatar jedie avatar jegger avatar pdallair avatar tito avatar tshirtman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

telenium's Issues

TeleniumTestCase :: remotely (android device) run app :: Connected to another telenium server

Description

TeleniumTestCase refuses to communicate with app because get_token request returns None.

    @classmethod
    def start_process(cls):
        ...
        # ensure the telenium we are connected are the same as the one we
        # launched here
        if cls.cli.get_token() != cls.telenium_token:
            raise Exception("Connected to another telenium server")

In the start_android_process function, the TELENIUM_TOKEN is sent along with other environment variables (perhaps specified by the user) to the android device as a file (/sdcard/telenium_env.json) but this file is never read and therefor the environment variables are never set.

Unfortunately there doesn't seem to be a way to set these environment variables remotely with adb so TeleniumTestCase can't setup the environment before launching the app. We could make use of custom android system properties but this would affect people who have worked around the current situation already by adding code that sets environment variables via /sdcard/telenium_env.json. So it's probably best to stick with the current approach. That said, I believe telenium should be the one loading up these environment variables when the client is started. Although the user doesn't have to do much from a python perspective he'd still have to give the app the right permissions to access this file. So I am adding a bit of code in telenium_client.py.

PR on the way soon.

Various logs and file contents

main.py

import platform

import kivy
import telenium  # Only use when app is launched on an android device

from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label


class FretboardDojo(App):
    def build(self):
        root_layout = AnchorLayout(anchor_x="center", anchor_y="center")
        widget_layout = BoxLayout(orientation="vertical", size_hint=(None, None))
        widget_layout.add_widget(Label(text='Test App'))
        widget_layout.add_widget(Label(text=f'Python {platform.python_version()}'))
        widget_layout.add_widget(Label(text=f'Kivy {kivy.__version__}'))
        root_layout.add_widget(widget_layout)
        return root_layout


if __name__ == "__main__":
    telenium.install()  # Only use when app is launched on an android device
    FretboardDojo().run()

buildozer.spec

[app]
title = Test App
package.name = testapp
package.domain = org.kivy
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
version = 0.1
requirements = python3,kivy,zipp,more-itertools,pytz,jaraco.functools,importlib-resources,tempora,six,jaraco.text,jaraco.classes,zc.lockfile,portend,MarkupSafe,jaraco.collections,cheroot,ws4py,Werkzeug,Mako,json-rpc,CherryPy,telenium
orientation = portrait
fullscreen = 0

android.permissions = INTERNET,ACCESS_NETWORK_STATE,READ_EXTERNAL_STORAGE
android.arch = armeabi-v7a

[buildozer]
log_level = 2
warn_on_root = 1

test.py

import os

from telenium.tests import TeleniumTestCase

# Only use when app is launched on an android device
os.environ['TELENIUM_HOST'] = '192.168.50.50'
os.environ['TELENIUM_TARGET'] = 'android'
os.environ['TELENIUM_ANDROID_PACKAGE'] = 'org.kivy.testapp'


class TestFretboardDojo(TeleniumTestCase):
    def test_startup_screen(self):
        self.assertExists("//Label[@text~=\"Test App\"]", timeout=2)

PyCharm Console Output

/home/pdallair/anaconda3/envs/telenium/bin/python /snap/pycharm-community/261/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py --path /home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py
Testing started at 9:40 p.m. ...
Launching unittests with arguments python -m unittest /home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py in /home/pdallair/dev/PycharmProjects/Telenium/TestApp

> app_quit: ()
Execute: ['adb', 'push', '/tmp/telenium_env.json', '/sdcard/telenium_env.json']
/tmp/telenium_env.json: 1 file pushed, 0 skipped. 0.5 MB/s (58 bytes in 0.000s)
Execute: ['adb', 'shell', 'am', 'start', '-n', 'org.kivy.testapp/org.kivy.android.PythonActivity', '-a', 'org.kivy.android.PythonActivity']
Starting: Intent { act=org.kivy.android.PythonActivity cmp=org.kivy.testapp/org.kivy.android.PythonActivity }
(None, None)
> ping: ()
> ping: ()
> get_token: ()

Failure
Traceback (most recent call last):
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/unittest/suite.py", line 166, in _handleClassSetUp
    setUpClass()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 120, in setUpClass
    cls.start_process()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 81, in start_process
    raise Exception("Connected to another telenium server")
Exception: Connected to another telenium server







Ran 0 tests in 8.076s

FAILED (errors=1)

Process finished with exit code 1

pip install telenium

rajat@rajat-Inspiron-5558:~$ pip install telenium
Downloading/unpacking telenium
Downloading telenium-0.4.1.tar.gz (326kB): 326kB downloaded
Running setup.py (path:/tmp/pip_build_rajat/telenium/setup.py) egg_info for package telenium
Traceback (most recent call last):
File "", line 17, in
File "/tmp/pip_build_rajat/telenium/setup.py", line 21, in
long_description = open("README.md").read()
IOError: [Errno 2] No such file or directory: 'README.md'
Complete output from command python setup.py egg_info:
Traceback (most recent call last):

File "", line 17, in

File "/tmp/pip_build_rajat/telenium/setup.py", line 21, in

long_description = open("README.md").read()

IOError: [Errno 2] No such file or directory: 'README.md'


Cleaning up...
Command python setup.py egg_info failed with error code 1 in /tmp/pip_build_rajat/telenium
Storing debug log for failure in /home/rajat/.pip/pip.log

Not able to click Spinner dropdown values

hello, I am working on the Graphical Ui test implementation of my desktop app and I have tried to do everything with x-path and not able to click the dropdown value of kivy Spinner so can anyone let me know how can we perform this?
This is the UI part
image

and here is the code:-
image
and I have tried to click on it by using this x-path
image

and it is not working so if anyone knows please suggest to me how to do it

Glitchy screenshot PNG

Description

Hello, this is probably more of a usage issue so you are free to redirect me elsewhere if need be.

I am running my app (see main.py) on my android device connected via USB. Building and deploying using buildozer. While the app is running, I run test.py on my VM. The various telenium function calls (connect,wait,screenshot) seem to work; nothing is crashing and no error messages in the logcat output (to be fair I am piping to grep "python", so I don't know if I'm missing anything). However, the screenshot.png file generated is well... innacurate (see the example I've linked to). When I run the app on my VM and run test.py connecting to this instance I do not have that problem, screenshot.png is spot on. So, there's probably some device configurations I need to set in order for this to work.

My attempt to debug this...

I looked at the telenium code and I see that on the main.py side of things, it uses kivy's Window.screenshot() static method to generate a temporary png file, reading the data, deleting this file before sending this data back to the setup.py side via HTTP. I would like to see if that temporary file generated on my device is the same as what I am getting on my VM. This would help narrow the scope of the problem a little. Unfortunately, I have not rooted my phone (and would prefer not to) and consequently, I do not have access to the telenium python files on the device where I could comment out the os.unlink(filename) line in order to checkout the no-longer-temporary png file on my device. I thought about using a local telenium copy when building and deploying the app but buildozer/python-for-android don't seem to conveniently support this. This might be achievable by creating a recipe but I am rather unfamilliar with this and it's becoming a bit too overwhelming to handle on my own...

So here I am, asking for help. Hopefully someone with kivy android app development wisdom has some answers for me. Either way thank for providing us with tools like this. I think I'll still end up using it for some pre-release integration testing, even if I can't take screenshots. Peace out.

main.py

import platform

import kivy
import telenium

from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label


class FretboardDojo(App):
    def build(self):
        root_layout = AnchorLayout(anchor_x="center", anchor_y="center")
        widget_layout = BoxLayout(orientation="vertical", size_hint=(None, None))
        widget_layout.add_widget(Label(text='Fretboard Dojo'))
        widget_layout.add_widget(Label(text=f'Python {platform.python_version()}'))
        widget_layout.add_widget(Label(text=f'Kivy {kivy.__version__}'))
        root_layout.add_widget(widget_layout)
        return root_layout


if __name__ == "__main__":
    telenium.install()
    FretboardDojo().run()

test.py

from telenium import connect

# cli = connect()  # For local connection
cli = connect(host='192.168.50.50', port=9901)  # For USB device connection

print(cli.wait("//Label[@text~=\"Fretboard Dojo\"]", timeout=2))

result = cli.screenshot('screenshot.png')
print(result["filename"])
print(result["data"])

Logs

logcat (main.py output)

12-07 16:08:13.328 20131  1472 V pythonutil: Unpacking private app
12-07 16:08:13.329 20131  1472 V pythonutil: Data version is d10dbb494b2d0cd46332cff3d7d47fab13cf803e
12-07 16:08:13.347 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libSDL2_ttf.so
12-07 16:08:13.347 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libmain.so
12-07 16:08:13.347 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libSDL2_mixer.so
12-07 16:08:13.347 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libSDL2.so
12-07 16:08:13.347 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libffi.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libhidapi.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libpython3.8.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libSDL2_image.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libcrypto1.1.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libsqlite3.so
12-07 16:08:13.348 20131 20131 V pythonutil: Pattern libsqlite3\.so matched file libsqlite3.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libsqlite3\.so against libssl1.1.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libSDL2_ttf.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libmain.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libSDL2_mixer.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libSDL2.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libffi.so
12-07 16:08:13.348 20131 20131 V pythonutil: Pattern libffi\.so matched file libffi.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libhidapi.so
12-07 16:08:13.348 20131 20131 V pythonutil: Checking pattern libffi\.so against libpython3.8.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libffi\.so against libSDL2_image.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libffi\.so against libcrypto1.1.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libffi\.so against libsqlite3.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libffi\.so against libssl1.1.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libSDL2_ttf.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libmain.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libSDL2_mixer.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libSDL2.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libffi.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libhidapi.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libpython3.8.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libSDL2_image.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libcrypto1.1.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libsqlite3.so
12-07 16:08:13.349 20131 20131 V pythonutil: Checking pattern libpng16\.so against libssl1.1.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libSDL2_ttf.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libmain.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libSDL2_mixer.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libSDL2.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libffi.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libhidapi.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libpython3.8.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libSDL2_image.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libcrypto1.1.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libsqlite3.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libssl.*\.so against libssl1.1.so
12-07 16:08:13.350 20131 20131 V pythonutil: Pattern libssl.*\.so matched file libssl1.1.so
12-07 16:08:13.350 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libSDL2_ttf.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libmain.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libSDL2_mixer.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libSDL2.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libffi.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libhidapi.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libpython3.8.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libSDL2_image.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libcrypto1.1.so
12-07 16:08:13.351 20131 20131 V pythonutil: Pattern libcrypto.*\.so matched file libcrypto1.1.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libsqlite3.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libcrypto.*\.so against libssl1.1.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libSDL2_ttf.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libmain.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libSDL2_mixer.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libSDL2.so
12-07 16:08:13.351 20131 20131 V pythonutil: Pattern libSDL2\.so matched file libSDL2.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libffi.so
12-07 16:08:13.351 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libhidapi.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libpython3.8.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libSDL2_image.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libcrypto1.1.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libsqlite3.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2\.so against libssl1.1.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libSDL2_ttf.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libmain.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libSDL2_mixer.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libSDL2.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libffi.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libhidapi.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libpython3.8.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libSDL2_image.so
12-07 16:08:13.352 20131 20131 V pythonutil: Pattern libSDL2_image\.so matched file libSDL2_image.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libcrypto1.1.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libsqlite3.so
12-07 16:08:13.352 20131 20131 V pythonutil: Checking pattern libSDL2_image\.so against libssl1.1.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libSDL2_ttf.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libmain.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libSDL2_mixer.so
12-07 16:08:13.353 20131 20131 V pythonutil: Pattern libSDL2_mixer\.so matched file libSDL2_mixer.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libSDL2.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libffi.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libhidapi.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libpython3.8.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libSDL2_image.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libcrypto1.1.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libsqlite3.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_mixer\.so against libssl1.1.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libSDL2_ttf.so
12-07 16:08:13.353 20131 20131 V pythonutil: Pattern libSDL2_ttf\.so matched file libSDL2_ttf.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libmain.so
12-07 16:08:13.353 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libSDL2_mixer.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libSDL2.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libffi.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libhidapi.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libpython3.8.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libSDL2_image.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libcrypto1.1.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libsqlite3.so
12-07 16:08:13.354 20131 20131 V pythonutil: Checking pattern libSDL2_ttf\.so against libssl1.1.so
12-07 16:08:13.354 20131 20131 V pythonutil: Loading library: sqlite3
12-07 16:08:13.357 20131 20131 V pythonutil: Loading library: ffi
12-07 16:08:13.359 20131 20131 V pythonutil: Loading library: ssl1.1
12-07 16:08:13.368 20131 20131 V pythonutil: Loading library: crypto1.1
12-07 16:08:13.369 20131 20131 V pythonutil: Loading library: SDL2
12-07 16:08:13.375 20131 20131 V pythonutil: Loading library: SDL2_image
12-07 16:08:13.378 20131 20131 V pythonutil: Loading library: SDL2_mixer
12-07 16:08:13.382 20131 20131 V pythonutil: Loading library: SDL2_ttf
12-07 16:08:13.386 20131 20131 V pythonutil: Loading library: python3.5m
12-07 16:08:13.388 20131 20131 V pythonutil: Library loading error: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk"],nativeLibraryDirectories=[/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/lib/arm, /data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk!/lib/armeabi-v7a, /system/lib, /system/product/lib]]] couldn't find "libpython3.5m.so"
12-07 16:08:13.388 20131 20131 V pythonutil: Loading library: python3.6m
12-07 16:08:13.388 20131 20131 V pythonutil: Library loading error: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk"],nativeLibraryDirectories=[/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/lib/arm, /data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk!/lib/armeabi-v7a, /system/lib, /system/product/lib]]] couldn't find "libpython3.6m.so"
12-07 16:08:13.388 20131 20131 V pythonutil: Loading library: python3.7m
12-07 16:08:13.389 20131 20131 V pythonutil: Library loading error: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk"],nativeLibraryDirectories=[/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/lib/arm, /data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk!/lib/armeabi-v7a, /system/lib, /system/product/lib]]] couldn't find "libpython3.7m.so"
12-07 16:08:13.389 20131 20131 V pythonutil: Loading library: python3.8
12-07 16:08:13.395 20131 20131 V pythonutil: Loading library: python3.9
12-07 16:08:13.396 20131 20131 V pythonutil: Library loading error: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk"],nativeLibraryDirectories=[/data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/lib/arm, /data/app/org.pdallair.fretboarddojo-IDt3PQV0j7LOzjHns8lr3A==/base.apk!/lib/armeabi-v7a, /system/lib, /system/product/lib]]] couldn't find "libpython3.9.so"
12-07 16:08:13.396 20131 20131 V pythonutil: Loading library: main
12-07 16:08:13.399 20131 20131 V pythonutil: Loaded everything!
12-07 16:08:13.462 20131  1485 I python  : Initializing Python for Android
12-07 16:08:13.462 20131  1485 I python  : Setting additional env vars from p4a_env_vars.txt
12-07 16:08:13.462 20131  1485 I python  : Changing directory to the one provided by ANDROID_ARGUMENT
12-07 16:08:13.462 20131  1485 I python  : /data/user/0/org.pdallair.fretboarddojo/files/app
12-07 16:08:13.462 20131  1485 I python  : Preparing to initialize python
12-07 16:08:13.462 20131  1485 I python  : _python_bundle dir exists
12-07 16:08:13.462 20131  1485 I python  : calculated paths to be...
12-07 16:08:13.462 20131  1485 I python  : /data/user/0/org.pdallair.fretboarddojo/files/app/_python_bundle/stdlib.zip:/data/user/0/org.pdallair.fretboarddojo/files/app/_python_bundle/modules
12-07 16:08:13.462 20131  1485 I python  : set wchar paths...
12-07 16:08:13.524 20131  1485 I python  : Initialized python
12-07 16:08:13.524 20131  1485 I python  : AND: Init threads
12-07 16:08:13.525 20131  1485 I python  : testing python print redirection
12-07 16:08:13.526 20131  1485 I python  : Android path ['.', '/data/user/0/org.pdallair.fretboarddojo/files/app/_python_bundle/stdlib.zip', '/data/user/0/org.pdallair.fretboarddojo/files/app/_python_bundle/modules', '/data/user/0/org.pdallair.fretboarddojo/files/app/_python_bundle/site-packages']
12-07 16:08:13.526 20131  1485 I python  : os.environ is environ({'PATH': '/sbin:/system/sbin:/product/bin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin', 'MOUNT_SYSTEM_OK': 'true', 'ANDROID_BOOTLOGO': '1', 'ANDROID_ROOT': '/system', 'ANDROID_ASSETS': '/system/app', 'ANDROID_DATA': '/data', 'ANDROID_STORAGE': '/storage', 'ANDROID_RUNTIME_ROOT': '/apex/com.android.runtime', 'ANDROID_TZDATA_ROOT': '/apex/com.android.tzdata', 'EXTERNAL_STORAGE': '/sdcard', 'ASEC_MOUNTPOINT': '/mnt/asec', 'BOOTCLASSPATH': '/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/knoxsdk.jar:/system/framework/knoxanalyticssdk.jar:/system/framework/smartbondingservice.jar:/system/framework/securetimersdk.jar:/system/framework/fipstimakeystore.jar:/system/framework/timakeystore.jar:/system/framework/sec_sdp_sdk.jar:/system/framework/sec_sdp_hidden_sdk.jar:/system/framework/drutils.jar:/system/framework/android.test.base.jar:/system/framework/ucmopensslenginehelper.jar:/system/framework/esecomm.jar:/system/framework/tcmiface.jar:/system/framework/QPerformance.jar:/system/framework/UxPerformance.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar', 'DEX2OATBOOTCLASSPATH': '/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/knoxsdk.jar:/system/framework/knoxanalyticssdk.jar:/system/framework/smartbondingservice.jar:/system/framework/securetimersdk.jar:/system/framework/fipstimakeystore.jar:/system/framework/timakeystore.jar:/system/framework/sec_sdp_sdk.jar:/system/framework/sec_sdp_hidden_sdk.jar:/system/framework/drutils.jar:/system/framework/android.test.base.jar:/system/framework/ucmopensslenginehelper.jar:/system/framework/esecomm.jar:/system/framework/tcmiface.jar:/system/framework/QPerformance.jar:/system/framework/UxPerformance.jar', 'SYSTEMSERVERCLASSPATH': '/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar:/system/framework/com.android.location.provider.jar:/system/framework/uibc_java.jar:/system/framework/ssrm.jar', 'DOWNLOAD_CACHE': '/data/cache', 'MC_AUTH_TOKEN_PATH': '/efs/TEE', 'KNOX_STORAGE': '/data/knox/ext_sdcard', 'ENC_EMULATED_STORAGE_TARGET': '/storage/enc_emulated', 'ANDROID_SOCKET_zygote_secondary': '21', 'ANDROID_SOCKET_usap_pool_secondary': '22', 'ANDROID_ENTRYPOINT': 'main.pyc', 'ANDROID_ARGUMENT': '/data/user/0/org.pdallair.fretboarddojo/files/app', 'ANDROID_APP_PATH': '/data/user/0/org.pdallair.fretboarddojo/files/app', 'ANDROID_PRIVATE': '/data/user/0/org.pdallair.fretboarddojo/files', 'ANDROID_UNPACK': '/data/user/0/org.pdallair.fretboarddojo/files/app', 'PYTHONHOME': '/data/user/0/org.pdallair.fretboarddojo/files/app', 'PYTHONPATH': '/data/user/0/org.pdallair.fretboarddojo/files/app:/data/user/0/org.pdallair.fretboarddojo/files/app/lib', 'PYTHONOPTIMIZE': '2', 'P4A_BOOTSTRAP': 'SDL2', 'PYTHON_NAME': 'python', 'P4A_IS_WINDOWED': 'True', 'P4A_ORIENTATION': 'landscape', 'P4A_NUMERIC_VERSION': 'None', 'P4A_MINSDK': '21', 'LC_CTYPE': 'C.UTF-8'})
12-07 16:08:13.526 20131  1485 I python  : Android kivy bootstrap done. __name__ is __main__
12-07 16:08:13.526 20131  1485 I python  : AND: Ran string
12-07 16:08:13.526 20131  1485 I python  : Run user program, change dir and execute entrypoint
12-07 16:08:13.663 20131  1485 I python  : [INFO   ] [Logger      ] Record log in /data/user/0/org.pdallair.fretboarddojo/files/app/.kivy/logs/kivy_21-12-07_2.txt
12-07 16:08:13.663 20131  1485 I python  : [INFO   ] [Kivy        ] v2.0.0
12-07 16:08:13.664 20131  1485 I python  : [INFO   ] [Kivy        ] Installed at "/data/user/0/org.pdallair.fretboarddojo/files/app/_python_bundle/site-packages/kivy/__init__.pyc"
12-07 16:08:13.664 20131  1485 I python  : [INFO   ] [Python      ] v3.8.9 (default, Dec  7 2021, 14:54:59) 
12-07 16:08:13.664 20131  1485 I python  : [Clang 8.0.2 (https://android.googlesource.com/toolchain/clang 40173bab62ec7462
12-07 16:08:13.664 20131  1485 I python  : [INFO   ] [Python      ] Interpreter at ""
12-07 16:08:14.434 20131  1485 I python  : [INFO   ] [Factory     ] 186 symbols loaded
12-07 16:08:14.636 20131  1485 I python  : [INFO   ] [Image       ] Providers: img_tex, img_dds, img_sdl2 (img_pil, img_ffpyplayer ignored)
12-07 16:08:14.666 20131  1485 I python  : [INFO   ] [Text        ] Provider: sdl2
12-07 16:08:14.836 20131  1495 I python  : [INFO   ] [TeleniumClient] Started at 0.0.0.0:9901
12-07 16:08:14.851 20131  1495 I python  :   * Running on all addresses.
12-07 16:08:14.851 20131  1495 I python  :     WARNING: This is a development server. Do not use it in a production deployment.
12-07 16:08:14.853 20131  1495 I python  :   * Running on http://192.168.50.50:9901/ (Press CTRL+C to quit)
12-07 16:08:14.857 20131  1485 I python  : [INFO   ] [Window      ] Provider: sdl2
12-07 16:08:14.877 20131  1485 I python  : [INFO   ] [GL          ] Using the "OpenGL ES 2" graphics system
12-07 16:08:14.878 20131  1485 I python  : [INFO   ] [GL          ] Backend used <sdl2>
12-07 16:08:14.878 20131  1485 I python  : [INFO   ] [GL          ] OpenGL version <b'OpenGL ES 3.2 [email protected] (GIT@fdd61e0, I20154638fb, 1602078382) (Date:10/07/20)'>
12-07 16:08:14.878 20131  1485 I python  : [INFO   ] [GL          ] OpenGL vendor <b'Qualcomm'>
12-07 16:08:14.879 20131  1485 I python  : [INFO   ] [GL          ] OpenGL renderer <b'Adreno (TM) 630'>
12-07 16:08:14.879 20131  1485 I python  : [INFO   ] [GL          ] OpenGL parsed version: 3, 2
12-07 16:08:14.879 20131  1485 I python  : [INFO   ] [GL          ] Texture max size <16384>
12-07 16:08:14.879 20131  1485 I python  : [INFO   ] [GL          ] Texture max units <16>
12-07 16:08:14.903 20131  1485 I python  : [INFO   ] [Window      ] auto add sdl2 input provider
12-07 16:08:14.904 20131  1485 I python  : [INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
12-07 16:08:14.980 20131  1485 I python  : [WARNING] [Base        ] Unknown <android> provider
12-07 16:08:14.980 20131  1485 I python  : [INFO   ] [Base        ] Start application main loop
12-07 16:08:14.985 20131  1485 I python  : [INFO   ] [GL          ] NPOT texture support is available
12-07 16:08:34.995 20131  1495 I python  : application request b'{"method": "select", "params": ["//Label[@text~=\\"Fretboard Dojo\\"]"], "jsonrpc": "2.0", "id": 1}'
12-07 16:08:34.998 20131  1495 I python  : application response <jsonrpc.jsonrpc2.JSONRPC20Response object at 0xbcee5d48>
12-07 16:08:34.999 20131  1495 I python  : application response {"result": ["/AnchorLayout/BoxLayout[0]/Label[2]"], "id": 1, "jsonrpc": "2.0"}
12-07 16:08:35.003 20131  1495 I python  :  192.168.50.101 - - [07/Dec/2021 16:08:35] "POST /jsonrpc HTTP/1.1" 200 -
12-07 16:08:35.024 20131  1495 I python  : application request b'{"method": "screenshot", "params": [], "jsonrpc": "2.0", "id": 2}'
12-07 16:08:35.041 20131  1485 I python  : (1396, 678, 3, 4188)
12-07 16:08:35.323 20131  1495 I python  : application response <jsonrpc.jsonrpc2.JSONRPC20Response object at 0xbcee5e08>
12-07 16:08:35.323 20131  1495 I python  : application response {"result": {"filename": "/data/data/org.pdallair.fretboarddojo/files/app/screenshot0001.png", "data": "iVBORw0KGgoAAAANSUhEUgAABXQAAAKmCAYAAADtpBZoAAAgAElEQVR4nOzab4hdd17H8e+9dyaZzkxuJ03IBlph2C3rIksM22UNuMJ4mYbSR6UUkbXUbUiPWtwa2liqLEsQZkZSKUUEH+z2j/XPPlkQsSKIbrNym21Xo6KCu7DaVlxduzRJ0zZpJ5OpD+bPPTNNQt0n+oHX69G5M+ec+zu/8zv3Du+kU1XvFwAAAAAA/+91/68HAAAAAADAhyPoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAAAABBC0AUAAAAACCHoAgAAAACEEHQBAAAAAEIIugAAAAAAIQRdAAAAAIAQgi4AAAAAQAhBFwAAAAAghKALAAA
12-07 16:08:35.325 20131  1495 I python  :  192.168.50.101 - - [07/Dec/2021 16:08:35] "POST /jsonrpc HTTP/1.1" 200 -

test.py output

> select: ('//Label[@text~="Fretboard Dojo"]',)
True
> screenshot: ()
screenshot.png
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x05t\x00\x00\x02\xa6\x08\x06\x00\x00\x00\xed\xa4\x16h\x00\x00 \x00IDATx\x9c\xec\xdao\x88]w^\xc7\xf1\xef\xbdw&\x99\xceLn\'M\xc8\x06Za\xd8-\xeb"K\x0c\xdbe\r\xb8\xc2x\x99\x86\xd2G\xa5\x14\x91\xb5\xd4mH\x8fZ\xdc\x1a\xdaX\xaa,K\x10fFR)E\x04\x1f\xec\xf6\x8f\xf5\xcf>Y\x10\xb1"\x88n\xb3r\x9bmW\xa3\xa2\x82\xbb\xb0\xdaV\\]\xbb4I\xd36i\'\x93\xa9\x0f\xe6\xcf=3MB\xdd\'\xfa\x81\xd7\xeb\xd1\xb93\xe7\x9c\xfb;\xbf\xf3;\xf7\x0e\xef\xa4SU\xef\x17\x00\x00\x00\x00\x00\xff\xefu\xff\xaf\x07\x00\x00\x00\x00\x00\xc0\x87#\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00B\x08\xba\x00\x00\x00\x00\x00!\x04]\x00\x00\x00\x00\x80\x10\x82.\x00\x00\x00\x00@\x08A\x17\x00\x00\x00\x00 \x84\xa0\x0b\x00\x00\x00\x00\x10B\xd0\x05\x00\x00\x00\x00\x08!\xe8\x02\x00\x00\x00\x00\x84\x10t\x01\x00\x00\x00\x00Bt\xef\xe8O\xd4B\xf7\x89\xea\x0c\xfa5sd\xb2\x06\xfd\x89\x1aL\xf5kf\xa6\xb5\xd7W\x9a\x1aN\x8f^\x8e~u\xa2\xbe\xd2\x0c\xab\xbf\xf9\xfa\xd6\xd6AOU3<\xb4\xb6yG\xbf\xa6\x17z\xb5\xb8\xfe>\xb3G&k\xd0\x9f\xae\xc1T\xbff\xab\xea\x93\xad\xf3=\xd5\x0c\xebo\xd7\x0e\xaa\xfe\xf4B\xf5\x16\xbb\xf5DgP\xfd\xd9n=89\xa8\xfe\xf4\xa0\xa6\xfa\xb3uwk{\xf4\xae\xa7\xea\xe9fX\xc7\xaez\xfcC59\xe8\xd7\xf4`\xaa\xfa\xb3U5;\x1a\xe9\xa9g\x9a\x1a~zc\xa8\xad\xf9\xb8\xaf5\x1f\xa3A\xd6\xdc\xb3M\r\x9f_\xdb\xbe\xb3\xbf\xbf\x16v,\xd6\xf8\xd2X\x9d\xec=^\xdd\':5\xe8\x1f\xac\xeeC\x935\xe8\xef\xaf\xf9\xa9~\x1d\xdc:iu\xe2\xf7\x9a\x1aN\x8c^\xb7\x86R\xcf5\xc3\xbaoc\xfc\x13\x0b\xeb\xe7\x9b\xa9{\'\x07\xd5\x9f\x18\xd4T\x7f\xa6\xb5\xff\xa9z\xae\x19\xd6\xdcU\xf6\x7f\xb0\xb5\x7f\xfb~\xfd~3\xacO]\xed~\xcd\xfdA5\xc3\xcfn\xde\xaf\x99\x85\xb1Z\xec-\xad\x9fo\xb6\x9a\xc9A\xf5g\xd6\xe6\xbb5\x15\xf5\x87\xcd\xb0f;UUwV\x7f\xffB\xedX\x1c\xaf\xa5\xb1\x93\xd5{|}\xde\x0fv\xeb\xa5\xc9A\xf5\xf7\xcf\xd7T\xff\xe0\xb6\xeb=Q\x7f\xf4\xbf\xba\xde\xb9\xfa\xea\xe6z\x1bl\xd9\xffpk\xff\xf9\xd6\xfc|\xb5\x19\xd6\xcc\xce\xeb\x8c\xef\xc9N\x1d\xd9\x1c\xdf\x93\xd5\xe9=[c\xed\xd7\xdd/\xd6\xe4\xa0_\xfb\xe7\xa7\xaa\xffdg}\xa4\xa3\xf1\xfcq3\xacC\xdd\xeb\x9c\x7f\xae[\xcfm\x9eo\xae\xbaO\x8f\xd6\xc5\xdc\xdd\xad\xedAk{\xed\xd4\xa3\xab\xf8\x93\xa6\x86\x9fZ\x7f\xef\xfeL-\x8c-Voic]\xffLM\x0e\xfa53\x98\xaa\xfel\xb7\x9eh\xdd\xa7\xc15\xb6?\xd1\x9a\xff?m\x86\xf5\xdb\x1b\xf3?\xb3Pc\x8b\xbdZ\xdaxN\xbbw\xb5\xce\xbdm\xbd\x9cx\xbe\x9a\xd1C\xb3\xf5\xf9\xbeo\xeb\xf3\xfd\xe9\xd6|\xfdY3\xacc\xd7\xbb\x1f\xc7\x1e\x1a\xcd\xf7\xb1^=\xb4c4/\xc7Z#\xaf\xfa\xabj6\x1e\xc2\xab\xac\xd7\xee\xb1\xc9\x1a\xf4g6\xc7\xd0>t\xee\xebM\r\x9f[\xdb\xbe\xb3\xbf\xb7\x16\xc6\x17kl\xa9W\'7\xaf\xfb\xde\x9a\x1c\xf4k\xef\xfc\xdau\x8f\x0e\x9d\xab\x17\x9a\xe1\xfa\xfa\xba\xb3\xfa{\x17j|q\xebs\xff\xe0\xe4\xa0\xfa{7\xd6z{\xbc\xa7\xaa\x19>t\xed\xf1\xfe\xec\xb6\xf1\xce\xb7\x0e\xfdFS\xc3\xd77\xc6{\xf5\xcf\x9b\xcf\xb5\x9e\xb1\xbb[\xdb\xdd/\xb5>\x87Zk\xec`\xeb!>\xf1\xd7M\r?\xdf\xbb\xee\xf9{c\xbd\xd1}9XU\x87Z\xf3y\xba\xa9\xe1\xf7\xaf=\x9f\x07\x9b\xc9\x1a\xf4\xf7\xae\xbd\xef\x97Z\xdb\x8f\xb6\xb6\xdbK\xeb\x9bM\x8d>\x8a\xb6\xaf\xf7\xa6\xb5&\xdb\xf3\xfbR5\xc3\xcfm\x0c\xa2\xf6.\x8c\xd7\xe2\xd8R\xf5N\x8e\xbe?\xe66\xef\xcd\xec\x96\xcf\xe3S/55l\xfd\xd3\xe6\\k\xeb\xe5fXG{\xeb\xf7\xfbj\xeb\xf5\xaen-n\xce\xf7]\xd5=1\x9a\xe3\xbbz7U\xa7\xf5\xbb\xaa\xcf\xb6\xc6{\xa6\x9a\xe1/Wg}\xbc\xfb\x17v\xd4\xe2\xf8R\x8d\x9d\xec\xd5\xe3[\xe6m\xfd~\xdd\xdb\xda\xee>\xbd\xe5^\xb4\xbf\xff\xfe\xae\x19\xd6=k3\xf7\xc1\xe7\xf9\xb1\xd6\x1a\x1b=\x94u\xe2\xef\x9b\x1a\xde\xda\xbd\xce\xfd\x9f\xab\xee\xf9\xd6\xe7S\xf7k\xa3\xf7\x9f\xab\xb5\xef\xb7u\xff\xd8\x0c\xeb\xe9\x8d\xef\x83\xf5\xe7c\xa9wr\xf4\xbd\xf8\x0f\xad{~\xb4\xb5\xdd\xbe\x95\xff\xdc\xd4\xf0/7\xc6\xf3\xc1\xf54\xd7;\xbd6\xaf{\xd7>S\xdb\x87\xfeK3\xac\x97\xeaZ\xef?[\xdd/\x8e\xdesv\xcb\x87\xc2\xb7\xab\x19\xdes\xed\xf5s\xf0\xd7G\x9f\t\xdb\xd6\x7f}\xa7\xa9\xe1=;\xaf3\x7f\xcfV\xa7\xf7\xdd\x1a\xdf\\\x0b\xcfV\xa7\xfb\xfch\x0e\x9f\xed\xb4\xff\x08\xaaS\xaf65<]\xd79\xdf\xc1\xea~m\xdb\xdf\x17\xed?\xbd\xfe\xbd\xa9\xe1ck\x9bw\xf4\xa7k\xa1\xb78\xba\xfem\x9f\xcd\x07\x1e9^\x0f\x1f\xbf\xbf\x8e\xd4\x81:\xfe\xc0cu\xbc\x0e\xd4#\xbf\xf6\x85:~\xff\x91\xaa\x03G\xeb\x81#\xbfZ\xbf\xf0\xf3M=|\xff\x17\xea\x81:P\x8f\xfc\xe2#u\xfc\xe1\xe3u\xff\x91\xfa\xe1u\xaa\xaaz\xdb~\xb8\xb6 _\x99\xb8\xca\xaeUUuCUUMTU\xed\xa8\xaa\xfa\xe9\xfa\x8df\xb8\xf6\xabC\x9f\xdfv\xae\xd1\xc3}c\xd5\x07\xff\xdb\xc2\x9e\x1b\xaaj\xa6\xc66\xce\xdf\x19\x1d5SU\xf5\x91\xad\xef\xbc\xe6c\xb5\xab\xaa\x0eMm\xfd\xe9\xd8\xe6\xd6\xda\r\xd8~U?\xb7\xbf\xaa\x0el\xfb\xe1\xf6S\x03\x00\xc0\x0f\xa9\xf3+\xbft\xf4\xfd\x17v\xdcX\xf5\xda\xd9\x9a\xdf3V\xcb\x7f\xb3\xab\xde\xbb\xedB\xfd\xc7\xae\x99\xfa\xf3\x957\xea\xd1Kg\xeab\xcd\xd5\xe53\xdf\xab]\xf3\xfbj\xf9\x9d\x17\xeb\xbd\xd5\xc3\xf5\xdd\xde\x1b\xf5\xe3S\xcf\xd4\xbbg\x1f\xadKg.V\xcd]\xae3\xdf\xdbU\xf3\xfb\x96\xeb\x9d\x17Wk\xf9\xf6\x89\xfa\xfe\xe5\xf3u\xcb\xe4\x0f\xaa\xf3\x9b7\xd7\xe5G/\xd5\xdang\xea\x9f.\xdf^\xb7\xcd\x9c\xads\xdd\x0b\xb5{u_-\xbf\xf3\x9d\xda\xd9\xfd\xb1:\xb7\xb2\xa3\xbe\xb5\xb2Z\x83\xb1\xd5z\xfb\xcb+u\xe5\xd1Ku\xe6\xfd=\xf5\x93\x97\xfe\xa2\xbe\xbdc\xbefwv\xea\xcc\xeb+5\xd8\xf7j]\\\xba\xa9&\x8e\xee\xae\xce\xf8\x85za\xd7x\xfdD\xe7\xc5z\xe5\xc2\xed\xf5\xc9\xde\xd9\xba\xe1_w\xd5\x1b\x1f?U\xd3\x17o\xab\x0b\xaf\xed\xae\xa9\x1f\xfd\xb7\xba0\xbe\xa7\xc6\x96\x9f\xaa\x95\xee\xd1\xda\xdd\x19\xaf\x0b/\xec\xa8\x1b\xeb\xb5:;\xbf\xa7\xc6\x96\xbfQo\xbc\xf7Su\xd3\x85\xdd5\xfe#o\xd5+o\xee\xacO\xd4\x8e\xfa\xfa\xae\xb7\xea\xb6\x0bgkO\x7f_-\xbf\xf3\xbb\xb5\xb2\xdc\xba\xd6\xb1\xd5:\xb4\\ue\xe2\xe5z\xfd\xcd\xc3u\xf3\xe4\xf9:\xfdn\xa7\x0e\xff\xd7J\xbd\xf7\x91g\xea\xca\xca5\xf6\xbd\xfc\x99\xba\xe5\xd2x\xadL\xbfXc\x9d\x8f\xd6\r+\xb7\xd6[oWU\xe7\xb7j\xfc\xca\x87<\xe6\xe2\xc7\xeb\xdc\xd4\xb9z\xe6\xe2J\xeb\xfe\x8c\xd5\xea\xda\x01\xf5\xf2\xebo\xd6\xe1\x9b\'\xeb\xfc\xe9w\xabs\xf8\xbfkeuwM\xbf\xb5\xa7\xde\xdd\xf5j\xed]\xdd]\xcbO\x8e\xd7\xd9\xd6\xfd\x18[=T\xcbu\xa5&^~\xbd\xde<|sM\x9e?]\xefv\x0e\xd7\x0f\xaa\xeac\xbb\x96\xeb\x95\x9d\xdd\xda\xbd\xb4\\+\xd78\xe6\xf2gn\xa9K\xe3+5\xfd\xe2Xu>:]\xe7ny\xbb:\xbf\xd3\xa9\xd5\x0f\xf1\x1e\xff9y~\xfd\xda&\xeb\xcb\xe7.\xd7\xd1\xdd\x9d\x1a\xbf\xf0B\xad-\xc9\xf9\xffi\xd4\xec\x83\x9b\xba\xce4\xfe\xd3\xd5\xb5\x84%,\xdb2\x18(,\x01B(\xc9\x92\x86b\x08$>\x06\xa5\xb6)q\x13\xd26\xdb\xdd\xedL7;\x9b\xe9\x9c\xcc\xeet3\x99d\xeaR0\xa0\xc4|l\x02\xed\x12\xe2@\xb8\xc6&\xd0m\x93\x99\xa64_$\x14L\x10\xc8n1\xc1,CHC\xbe\x8ciB\xc8\x80|-_[\xb2-\xdd\x8f\xfd\xe3\nl\x12\xb3\xc9\x7fW:\xe7\xb9\xefs\xde\xf7y\xdesf\xee\xa1D\xcd\xf0v\xc1\x10e\xc6y\x82\xc1\xc9\x8cy:\x9f\xee\x11\xef}7\xaf\x8c\xb9\xfe\x0e\xfa\x8d\xa5\\4\x87\x98\xb0\xcb\xfa\x12\xcf\x96n\x87E%\x058\xf9\xbd\x10Sa\xe9\x0e\xcc\xcc\x15\x1d\x14\x90\xb7\xd0C\xdb9\x83\xea9^\xf4\xfc\xfd$\xd2\x11&\x1e>\x8b\x1a\xb9\x95\xe0\xa9\xed\xa4o\x1cQ\x97w\xf3(\x9b\xeb\xa7#\r\x93\xf3<LQ\r\xcc^\x87]\xfe\x91\xb5x\x97\xbc\xb2\xb9\xf8;\xd2P\x92\x8f3\xcd\xcf\xaf\xf3?\xbfN\xad\xb2\xdc>e\x80<s,m\xaa\x87\x9b\x82:\xd3S\n\x9b=\xf6\xe8\xef\x9b\x91O\xfa\xef\x06\x08\x9a\x05\xf4n\xef\xbfNM\xfe\x86\xbap*V\xa1M\xf7\xa0\xca\x89,,\xfd,@2\x17\'\xf0\xa9\x89g\x8aJ\xc6\xcc\xb05?5:\xafOR,\x9c\x95\xa5=;\xac\xe9\xfe\xfc\xd1\xbc\xf36\x05Ce\x18z\t\xa1\xd2\x0c\xa9\xed&\x99\xaf\xa8{\xa6p6\x83\xcee\x8aS\xf3\xf8\xb5W\x1fe\x9d\xfd\x18K?\x86\x9e\xd9\x98\x85Cx?\x84\xa2\xc9\x01\x92\xc1\xa7\xf1\xe9\xa3{\xe4\x93\xd4Bfe\xdb\xc9~QS\x83\xfaW\xaf\xaf{\x1cf\xf1F2f-\x03\x1d\x0e%\xe5\x03\x1c8\x97\xa2zZ\x02}\xccy\xfc\xbd\xd5\xb0k\x80\xa1\xaf\x93\xeb\x8cJ\xcdE\x13sr\x80d\xa7\x855\xdd\xcf\xae\xcc\xff\xa7\xeb\x8b\x84\x02\x93y\xba\xcf\x7fuNA\xdeB<m\xe70\xaa\xe7\xe0\xd5\xf3\xd9\x7f\xf12\xcb\xb3\x16\xf6T\x0fCA?A\xcb\xc4i+\xc0(38_\x1c\xe4\x9b\x9d\x06y%*\x99\xa6<R\xd7\xf1\xc6G\x81!n\xc5C\xca\xf1\xd1\x134)\xde\xd8K\xfe\x95\xfeyM\xff7\x19X\xa0RTt\x98C\x87\xc6r\xea\xdb\x8b\xaf\xe1\xdeiT3\xcb\xec\xc7H\x86`f\x92\xf6!\xa8\xf15bt\x8f\x9e;_j)\x17\x03I&<\xed\xbbF\xab\x17\n\xaa(\xcd\xa4h\x1b\x08\xf0]3\x8b\xbd\xcbv{R\xae\xdf\x9fKU3-\xa13\xe6\xbc\x8f\xd4\xd7\xf1\xeb\xbe\x0e\xda\x97\xdc\xc5B[\x81\x0b6\x81\xaf\xec\xf99\xdd^\x86P\x89J\xc6\xb6@=\x8f\x8f\xa9(\x81b6\x1b\xe6\xe85\xf3\xf8X\xe8\x9c\xa2\xc83\x93\xe4X\x8d\xbc\x9e\x11z|\'KuY\x11z\x8f\x82QlS\x9aI\xf1\xbe_\xe1\x96\x1e\x13\xdfq0\xab\x8bP\x8d\x93\xf4\x04\xa7\xa2\x0c\x95P\xda\x95!{\xc5\x87(\xa3\xc7\x0b\xfb(\xb7\xfa\xe8\xca\x14\xf2f_\xe6\xea\x1c;TF~z\x0c}\xc16z\x8c\x05\xcch/\xa4\xf7Kz\x08\x91\xff\xf0A\xf0\x953p\xc0\x8bwA\nK\xe9\xa0+\xb0\x80\xf1\x96B\xff\x18\x95\tN\x1b\x03z5\xca\xe7\xfd\xe4\xcf\n2\xd0\xd9Ca\xa9\x9f\xcd\xb6\xefj\xacL0Bq\x1ahW\xe9\xadn\xa1\xd3\x8cpcf\x88\xc2\xfc\x0c\xce@\x88L\x9b\x97\x81/\xc56QF\xd5\x97{\xbe\xb8L\x88\x125\x83m\x81\xda\x9c\x1a\xd6\xe2\x17\xf7\xf2\xfd\t\xd2\x91\x89\x1c>\xab\x12\xb95\xc8\xa9\xedin\x1c\xa1\xa3\xf3YA\xa9\'@\xfb\xfb\xa9\xdcx7s\xaf\xbc\xcb\xb1\xa82K\xe9\t\xe9t\x9c\x1fG\xf5\xf4\x04\x99s\xe0\x99\x16@\xfd\xc0\xc0\x1c\xe7c\xa0\xf8\x10z_\r\xd3\x02*\xa7\xfd}\xdcl\'\xf0\xf7\xce$\xd9\xde\x83Z=\x96AO\x1f\xfes\n\xbei\x01\xd4\xd3~\xfan\xb6i\x1cQ\x87/z\xf5\xbdqY\xe6\x00\xfb>\xecf\xf9U]\xa5\xf0\x99\x93\xb0U%w\xa6\xe8d\\\xd1\x1c\xe0=\xac\xec7\xe94\xf2(Q34\x99\xca\xf5{@"Md\xe2>:\xda\x97p\xd7B\x1b\x85\x0b\xd8\x81\xd1\xb1\x8eU\x85Y\xdaCH\xef\xc0P\xab\x19\xeb\xd5\xc9?\xfa9o$\x90\xf6\xb7\x00\x00\x07\x08IDAT\x97\xdf\xe2\xe6\xf4<\xa4\xae\xac]\xf9\x01\x85/\x7fH\xd1\xf7f\xe3?\xdcCb\xe9\xc7\xa8\x8e\x1b\xf3\xe3\x82nfm\xcd\xe2\\\xaf\x8e\x0b\xfc\xd8\xf9\t\x9a\xbc\x05<t8\x832\xdfO6p\x10K\xfd\x0e\x1d\x9f\x9ca*\xdffVI\x82^\xa7\x83\xb1\xf97\x91f\x1a\x01\xf5\x14C=\x7f\x8f\xa3\xa6\xd9a\x06\xae\xbb\xde\x8f\x0b\xba\x99\x15\xfb+\x99\xdc\x1e\xdc=wt\x0f\x87}\xe5X}]d\n\xa7\xa0\x1a&\xbdN\x1fc}\xc58\xcf\x9a0\x92\xf7;i"3L\xd4D\x01\xd6l?\x87\xcd!\xca2\x1eHy\xd8egF\xf7^\x91\xca\xed\t\x15Ow7\x85\x93\xc7\xd3{\xa9\x8f\xf1\xe1\xed\\\xcc\xbf~/\xbaxy9Y\xcbf\xaag\x88\xa0?\x88e:\xb4\xbd\x97\xceis3GG;\x84\x03\xce]O \xeb\x8f\xd2(Z(FA\xff\x96\r\xa7=\xac\x93q\x12\x9a`K\x18\x14}\x196\xfb\xf1\xac\x97\xc4\xdf\xd4\x10\xadaPt\x1e\xb4\xa1\xf9\xc8z\xa4w\x02M\xe2\xa7\x14\xa2\xa0\xd7\xd9\xb0\xee\x08OJ/\x934\xc1\x03aP\xf4\x1d\xd8<\xc4\x91\xa7$\xdeE\x1ab\xb1\x8b\x8f\xd9\x10\xf1lF\xc6\xbb\xd0D\x03a\x14\xf4\xb36\xcc>\xc2f\xe9\xe5\'\xcd\x82\x89!Ptp\x00\xb6J\xe21\r\xb1\xd7\xc5\xdf\xea\xc0;\xb1\xadH\xef\xf3h\xe2\xa4\x8b_\xee\xc0\xabQ\x9e\x91\x95\xfcR\x13\xf4\x87A\xd1\x7f\x8e\xc3&h\x90\xc4Wh\x08\xf7O4\x07d\xb4\x01Y\x99@\x13Q\x17\xdf\xe6@y\x94ge%M\x9a\xe0d\x18\x14=\x81\xc38"\xdb$\xf5\xb5\xc3\xf8" yx\x1b\xd2\xdb\x8c&N\xb8\xf8\xdb\x81\xe3k\xd9.+\xf9\xad&pS\xf5C`/K\x9e\x93\xd4\'5\xc4\n\x17\xff\x1f\xc0\xb6%;\x90\xf5\x8d\xc3\xf8\r\xc0J\x07M\xc6Ij\x82\xda0(\xfa\x0b\xc0\x8fq\x1a%\xf1\xc74\x84\xe1\xe2\xe3@\xc5\xdaFde\x13\x9a8\xe6\xe2?\x04nr\xd8)\xe3<ru\xfd\x0e\xe0a\xedNI\xe5\xa3\xc3\xf8\xc9\x1e\xb8`7!\xe3\x8d\xc3\xf8{=\xf0\xda\x1a\x9ad%\xb7i\x82\xf9aP\xf4\xff\xc4\xc33\xbc\xd5,\xf1\x9e\xd6\x10\xae(x\xca\x03\xb5o\xedBz\x9f\x1d\xe6\xff\x07\x0f\xdc\xbf\x98\xe7e=\xe34\xc1=aP\xf4Sx\x98\xcb\x9a\xdd\x92\xca\x874\xc4\xa0\x8bOy h\xefA\xc6[\xd0\xc4\x1e\x17?^\x81\xcb\x87\xd8#\xbd4k\x82X\x18\x14}\x0e\ngX\xfd\x1bI\xe5\x7fk\x08\xb7(\xfc\xb3\x02/V\xfc\x0f\xb2\xfe94\xd1\xea\xe2\x1fS\xe0W\x16\xbf\x95qV5\n\xba\x8a\xdd\xfc)\xfc\x98\xd5\xbf\x93T\xee\xd7\x10{\\\xfc1\x05\x16U\xbc\x80\xac\x7f\x08M\x18.\xfe\x82\x02\x93\x0f\xf1\x82\xf4\xf2\xef\xbb\x05\xc9 (\xba\x82\x17\x1b\xf1GI\xfd\x93;\x11\xc7\x8a@\xd1\x99\xe2\x85O[^Az\x1f\xa7Q\x9ct\xfd3\xdf\x0b\'\xeaxMVrN\x13<\x1c\x06E\xaf\xc1\xcb\x1b\xd4\xbd.\xa9\x8cj\x88\x13n\xfc_x\xe1I\xb1\x0fY\x7f\x90\xddb\x0bA\x14\xf4]^\xf87\x93C2\xce\xc0\xd5\xfc\xb5\xe0\xa5\n\xf1\x96\xa4\xfeS\r\xe1\x9a\x8a>/\x14\x88\xc3\xc8\xfa\xf5h\xa2\xc5\xe5\x1fR\xc1\xc8\x12\x93q\xf6j\x82\xadaP\xf42T:\xc8\x1e\x91\xc4o\xd6\x10\xa5.\xfe_U\xd8\xbd\xea(\xb2\xb2\x99&\xf1\xbc\xeb\xdf-*<R\xce\x9fe=34\xc1\xc40(\xfa+\xa8\xdc\xc7\xaa\xbfH*\x7f>\xec\xffWT\xb8/{\x0c\x19\xdf\x8a&~\xe7\xc6?\xad\xc2\xb7\x0erLz\xb9S\x13\xd8aP\xf4K\xa8\x94R\xde.\xa9olB\xec,\x04Eg~\x1e\x9c\xc8t \xe3\xbbh\x14\rn\xfej\xf3\xe0\xa9\x03\x9c\x94^6h\x82\x97\xc2\xa0\xe8\xbf!\x8f\x7fa\xe5\xffJ*\x7f\xb4\x13\xf1\x91\x9b\xff\xcf\xf2\xe0\x1b\x99\xd3\xc8\xf8\t\x1a\xc5\x83.\x1e\x1f0\xc4\x19\x19\xe7\xf3\x9d\x82\xaa"P\xf4[\xf0\xf1W\x86\xde\x93\xc4{5\xc4"\x97\x7f\x8d\x0f\xde\xb8\xe3,\xb2\xbe\x0eM\xbc\xe4\xf2\x7f\xc4\x07[\x86x_\xc6Y\xb5[\xf0R\x10\x14}\x0b>\x1e\xe1O]\x12\xefg\x1a\xe2N\x17\xff\x9a\x0f\xee\x1d\xfa\x1b2\xbe\rM\xfc\x97\x8b\xff\x99\r\r\x0e\x8e\x03\xca\xaa\xfbq6\xdeB\x88\x8d\xd8c-\xb2}~2\xfe,>\xd3\x87\x95g\xa1\xda^\x1c\x05<\x1eP\x1c/\x96jrG\xf6N\xfeR\xfegD[\x05\xad\x8b\xe3,9\x1a\xe1\xc8]1\xbes\xb8\x92\xb7\xaa\x0eQ\xdd\xb2\x94\x83\xdf=\xc0\xb2\x03w\xf3\xa7\xbb\xf7S\xf3\xe6\xf7x\xe3\x9e}\xdc\xfb\xfar^\xbb\xefU\xbe\xff\xca\x0fx\xf9\x87\x7f\xe4\xfe\xbd\xff\xc0\x1f~\xf4\x12\xff\xf8\xfb\x7fb\xcf`\x07p\xc6m\xfa\x91\'\x90\xeb\xdc~\xef\xd4\x84\x98X>\xc8\xc3\xd1\xc7Y\xb3\xbe\x8e\x8d+6Q\x1b\x89r[\xac\x81\x0f"?#\xa4X\xa4\x13)\x8cS3\x81\x8fr\xbb\xc6:dk\x02Ml\x81e!\xc6T\xf4\xb3\xa1.B\xf4\x86\x18U\x97"\xb4\xd8`\xf9:I\x19]\x8cD\xad\x97\xad\xbc\xa9\tZYF\xa8\xa8\x82t\xed\x1a\xea\xeb6\xb12\x12\xe5\x86\x99&3^\xf4\x81e\xd39\xdd\xa0+G5\xb6^\xa2NhB\xfc\xd4\xa2&4\x91\xf2\xc1\x87\x89>\xbe\x86\xf5u\x1bY\xb1\xa9\x96Ht\t\xb1=\xc7\x89<\x10B\xb1\xd2\x98)\x83\xd8"\xc8}Y\'\xf6\xa4D\x9d\xa4!\x1ep/hT\xa4kYS_\xc7\xa6\x95.\xdf{.Ex\xdd\x07\x96\xdd\xc9\x1d\xe6\x0c\x8e\xe7\x9e\xef6gp \xf7\x9c\x9a\xd5E\xee\xa6\x1f\xb1\xa7$\xea"\r\xb1\x98\xeb\xf0\xb9\x8d\x99f\x98\x17C\nV:\xc1\xc0\xd2\x0f\x88\x1cp\xb9%R\x06\x83\xc0\xd9\\>6\xcbV\xba4A\x035\x84\xc6\x953\xf0\xe8Z\x9eX\xbd\x81U\x9b~A$z\x1b\xb1\xc8\x07Db\x01\x14+C"5\x95SW\xea\x17\xdb\x8cT\x7fB\xb3\x98\x88y\xbd\xfa\x1d\x99\xc1\x19\x7f\x98@\x8eG\xca\x18\x19y+\xb25\x86&\xf6\xba\x17\x08\xca\x07xt\xedzVo\\\xc1\xa6\xda\x08\xd1\x1bn\xc7\x9c\xb1\x8d\x80b\x91\xf9(\x85\x01\xd0\x95\x0b\xbdU\xa2>\xaf!N\xba\x17\x10+\xfa7P\x17\x89R\xf8\r\x93y\xaf\xda`\xf98\x99g\x90L\xba\xf3\xa3\xcfH\xaa~\xa9!\xfa\xdd\xdfE@n\x88\x06\xd9\xca\nM\xe0\x0e\xcd\x1e\xe6\x17m@V\xb9\xfb\xf15\xfa*\\\x849\xaf\x01\x1b\x0b\xdfI\x87\xf9v.\xdex\x83d\x8e_\xf4YIU\xd3\xd7\xe7\x17\xd9&YW;\xcco\xda\xd5\xa5\xc6\xd8&U\x9a5\xc1\t\x96\x11\x1aSA\xff\x86:"\xd1B\xa6\x98\xf3x\xd9\x06\xcbw\x92IF2\xa7\xef(\xdbe\x95\xbb\xdf\x7f\x95\xbe\'\x19t\xe5L\x11yN\xb2.\xa9!V\xb8\x17 *R+Y\xbdi\x15\x91\xe8\r\xc4\x16]"rL\x01K\xa13\x15\xa6\xebJ\x11";\x90\xeb\xdc\xf3\xc2\xb5\xf9\x99\x829\xef\xe5\\~\xa6c$szAC\xb6&\xd1D\xad{\x81g\x14\xbd,\x89=\xc8\xf1H\xb3\xebw3\x85\x11\x1bY\xa9Fd\xebch\xc2\xf8b\x92\x886\xe6\xf2}\x0c\xfe\x0f\x0f\xbc\xd0\x83\x06\x96\x9c\x02\x00\x00\x00\x00IEND\xaeB`\x82'

screenshot.png

https://drive.google.com/file/d/1xrTJYCeZoFtRYFIZEmjRad3MH7wwyx0A/view?usp=sharing

select on text attribute that contains ',' gives server error

I was testing mine app that has a list of widgets of OneLineListItem, to know which one to click I choose to select by text it contains,
in my case it is a location in this format; Country, City, so for example "Argentina, Buenos Aires"

The problem with telenium is that if I try this xpath locator:
'//OneLineListItem[@text="Argentina, Buenos Aires"]' I got server error:

> select: ('//OneLineListItem[@text="Argentina, Buenos Aires"]',)
Traceback (most recent call last):
  File "/home/magowiz/.virtualenvs/holiday/lib/python3.10/site-packages/telenium/client.py", line 36, in __call__
    return response["result"]
KeyError: 'result'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.10/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<console>", line 1, in <module>
  File "/home/magowiz/.virtualenvs/holiday/lib/python3.10/site-packages/telenium/client.py", line 60, in wait_click
    if self.wait(selector, timeout=timeout):
  File "/home/magowiz/.virtualenvs/holiday/lib/python3.10/site-packages/telenium/client.py", line 50, in wait
    matches = self.select(selector)
  File "/home/magowiz/.virtualenvs/holiday/lib/python3.10/site-packages/telenium/client.py", line 38, in __call__
    raise TeleniumHttpException(response["error"]["message"])
__main__.TeleniumHttpException: Server error

A workaround that I find is to avoid using comma in attribute text matching rule, using this one:
'//OneLineListItem[@text~="Buenos Aires"]', this is ok for me because in search field I already insert whole location and there should not be other Buenos Aires in Argentina.

Is there a way to escape comma properly before sending xpath to telenium?

ImportError: cannot import name parse_http_list

I run on the Android platform using the PyDroid2 application, where I execute the telenium file and bring up the following message.

storage/emulated/0 $ telenium Traceback (most recent call last): File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/bin/telenium", line 11, in load_entry_point('telenium==0.4.2', 'console_scripts', 'telenium')() File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/pkg_resources/init.py", line 487, in load_entry_point return get_distribution(dist).load_entry_point(group, name)
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/pkg_resources/init.py", line 2728, in load_entry_point
return ep.load()
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/pkg_resources/init.py", line 2346, in load
return self.resolve()
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/pkg_resources/init.py", line 2352, in resolve
module = import(self.module_name, fromlist=['name'], level=0)
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/telenium/web.py", line 8, in
import cherrypy
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/cherrypy/init.py", line 73, in
from ._cptools import default_toolbox as tools, Tool
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/cherrypy/_cptools.py", line 33, in
from cherrypy.lib import auth_basic, auth_digest
File "/data/data/ru.iiec.pydroid2/files/arm-linux-androideabi/lib/python2.7/site-packages/cherrypy/lib/auth_digest.py", line 27, in
from six.moves.urllib.request import parse_http_list, parse_keqv_list
ImportError: cannot import name parse_http_list

select() may generate an identifier that is unusable

When using the select() function, the provided path cannot necessarily be used for a subsequent select() (or getattr(), etc) and will not properly select any items.

This appears to arise because the XPATH index syntax is slightly different than the path_to syntax use different semantics.

Specifically, the current to_path syntax uses the index of the element in the child widgets list.

def path_to(widget):
from kivy.core.window import Window
root = Window
if widget.parent is root or widget.parent == widget or not widget.parent:
return "/{}".format(widget.__class__.__name__)
return "{}/{}[{}]".format(
path_to(widget.parent), widget.__class__.__name__,
widget.parent.children.index(widget))

However, the XPATH syntax uses the index into the list of previously filtered items. This means that if any items are filtered out, the index used by XPATH and the index into the Kivy child list are no longer equivalent.

TeleniumHttpException: Method not found

>>> cli.click_at(wallet) Traceback (most recent call last): File "<console>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/telenium/client.py", line 37, in __call__ raise TeleniumHttpException(response["error"]["message"]) TeleniumHttpException: Method not found

FileNotFoundError: [Errno 2] No such file or directory: 'README.md'

Trying to install from pypi is failing with a FileNotFoundError: [Errno 2] No such file or directory: 'README.md'. I thought it was because of the missing README.md from the manifest file, but it works from GitHub zip archive. I'm running Python 3.5.2.
See debug session.trace below:

[andre:~/workspace/EtherollApp] [venv] develop* ± pip install telenium==0.4.1
Collecting telenium==0.4.1
  Using cached telenium-0.4.1.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "/tmp/pip-build-7ssf893v/telenium/setup.py", line 18, in <module>
        import pypandoc
    ImportError: No module named 'pypandoc'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-7ssf893v/telenium/setup.py", line 21, in <module>
        long_description = open("README.md").read()
    FileNotFoundError: [Errno 2] No such file or directory: 'README.md'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-7ssf893v/telenium/

Now from Github zip archive:

[andre:~/workspace/EtherollApp] [venv] develop* 1 ± pip install https://github.com/tito/telenium/archive/0.4.1.zip
Collecting https://github.com/tito/telenium/archive/0.4.1.zip
  Downloading https://github.com/tito/telenium/archive/0.4.1.zip (331kB)
    100% |████████████████████████████████| 337kB 2.1MB/s 
Requirement already satisfied: Mako>=1.0.6 in ./venv/lib/python3.5/site-packages (from telenium==0.4.1)
Requirement already satisfied: CherryPy>=10.2.1 in ./venv/lib/python3.5/site-packages (from telenium==0.4.1)
Requirement already satisfied: ws4py>=0.4.2 in ./venv/lib/python3.5/site-packages (from telenium==0.4.1)
Requirement already satisfied: json-rpc>=1.10.3 in ./venv/lib/python3.5/site-packages (from telenium==0.4.1)
Requirement already satisfied: Werkzeug>=0.12.2 in ./venv/lib/python3.5/site-packages (from telenium==0.4.1)
Requirement already satisfied: MarkupSafe>=0.9.2 in ./venv/lib/python3.5/site-packages (from Mako>=1.0.6->telenium==0.4.1)
Requirement already satisfied: cheroot>=5.9.1 in ./venv/lib/python3.5/site-packages (from CherryPy>=10.2.1->telenium==0.4.1)
Requirement already satisfied: six>=1.11.0 in ./venv/lib/python3.5/site-packages (from CherryPy>=10.2.1->telenium==0.4.1)
Requirement already satisfied: portend>=2.1.1 in ./venv/lib/python3.5/site-packages (from CherryPy>=10.2.1->telenium==0.4.1)
Requirement already satisfied: more-itertools>=2.6 in ./venv/lib/python3.5/site-packages (from cheroot>=5.9.1->CherryPy>=10.2.1->telenium==0.4.1)
Requirement already satisfied: tempora>=1.8 in ./venv/lib/python3.5/site-packages (from portend>=2.1.1->CherryPy>=10.2.1->telenium==0.4.1)
Requirement already satisfied: pytz in ./venv/lib/python3.5/site-packages (from tempora>=1.8->portend>=2.1.1->CherryPy>=10.2.1->telenium==0.4.1)
Installing collected packages: telenium
  Running setup.py install for telenium ... done
Successfully installed telenium-0.4.1
[andre:~/workspace/EtherollApp] [venv] develop* 2s ± 

Python 3 support

Currently, the embedded python jsonrpc library doesn't support Python 3. And some part of telenium too. We need to get around it.

tearDownClass() failure

Sometimes (about 1 time in several runs) tests end with a JSONDecodeError. Here is the full trace:

Failure
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/suite.py", line 290, in _tearDownPreviousClass
    tearDownClass()
  File "/Users/denisdarahan/PycharmProjects/NewProject/venv/lib/python3.9/site-packages/telenium/tests.py", line 126, in tearDownClass
    cls.stop_process()
  File "/Users/denisdarahan/PycharmProjects/NewProject/venv/lib/python3.9/site-packages/telenium/tests.py", line 114, in stop_process
    cls.cli.app_quit()
  File "/Users/denisdarahan/PycharmProjects/NewProject/venv/lib/python3.9/site-packages/telenium/client.py", line 53, in __call__
    response.json()["error"]["message"])
  File "/Users/denisdarahan/PycharmProjects/NewProject/venv/lib/python3.9/site-packages/requests/models.py", line 900, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/[email protected]/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Actually it happens because response.text is an empty line.

how to embed telenium with mobile automation.

i wanted to embed the telenium with andorid device . i mean to say i am able to run the mai.py with telenium library and it provide me output on console but i wanted that console output should work on android device . it means when the script get run than it will automatically automate in the android device and run my apk on it.

suggestion: implementation of click and hold behavior

To interact correctly with MDSwitch widget, I needed to have a click and hold behavior in order to change its state:
click_on and wait_click methods from client are not working in this case, so I found a tricky workaround for this that I would like to share:

I managed to do this using wait_drag client method, putting as selector the Thumb and as target the same, specifying a proper duration and timeout, in this way I was able to reproduce desired behavior.

Here it is the code I wrote:

switch_locator = f'//MDSwitch[@name~="{provider_name}"]/Thumb[0]'
cli.wait_drag(switch_locator, switch_locator, duration=3, timeout=30)

Maybe it could be useful to implement a click_hold_on or a wait_click_hold method inside client that can use this "trick".
What do you think?

cannot click on the navigation drawer using telenium.

Hello as i am creating test cases for kivy app. so in my application there is a navigation drawer and i am trying to access the xpath of the navigation drawer and toolbar but unable to get the xpath of both of them . even when i am using cli.pick() method on telenium IDE even there not getting the xpath so please help me to find xpath of it.
image
image
image
image

TeleniumTestCase :: remotely (android device) run app :: RemoteDisconnected

Description

Sending an app_quit request often causes a remote disconnection. This is no surprise. It's simply impossible for the app to send a proper response if it's not running anymore. The way telenium_client.py is coded right now... I don't know if there's a way to make sure the response is sent before closing the app. So what I'm doing instead is simply catching the error and ignoring it if it stems from an app_quit request.

PR on the way soon.

Various logs and file contents

main.py, test.py & buildozer.spec

All the same a in #20

PyCharm Console Output

/home/pdallair/anaconda3/envs/telenium/bin/python /snap/pycharm-community/261/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py --path /home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py
Testing started at 10:12 p.m. ...
Launching unittests with arguments python -m unittest /home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py in /home/pdallair/dev/PycharmProjects/Telenium/TestApp

> app_quit: ()
Execute: ['adb', 'push', '/tmp/telenium_env.json', '/sdcard/telenium_env.json']
/tmp/telenium_env.json: 1 file pushed, 0 skipped. 0.6 MB/s (58 bytes in 0.000s)
Execute: ['adb', 'shell', 'am', 'start', '-n', 'org.kivy.testapp/org.kivy.android.PythonActivity', '-a', 'org.kivy.android.PythonActivity']
Starting: Intent { act=org.kivy.android.PythonActivity cmp=org.kivy.testapp/org.kivy.android.PythonActivity }
(None, None)
> ping: ()
> get_token: ()
> select: ('//Label[@text~="Test App"]',)

Error
Traceback (most recent call last):
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/client.py", line 36, in __call__
    return response["result"]
KeyError: 'result'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py", line 13, in test_startup_screen
    self.assertExists("//Label[@text~=\"Test App\"]", timeout=2)
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 136, in assertExists
    self.assertTrue(self.cli.wait(selector, timeout=timeout))
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/client.py", line 86, in wait
    matches = self.select(selector)
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/client.py", line 38, in __call__
    raise TeleniumHttpException(response["error"]["message"])
telenium.client.TeleniumHttpException: Server error



Ran 1 test in 4.156s

FAILED (errors=2)

Failure
Traceback (most recent call last):
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 445, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/http/client.py", line 1371, in getresponse
    response.begin()
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/http/client.py", line 288, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/util/retry.py", line 532, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/packages/six.py", line 769, in reraise
    raise value.with_traceback(tb)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 445, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/urllib3/connectionpool.py", line 440, in _make_request
    httplib_response = conn.getresponse()
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/http/client.py", line 1371, in getresponse
    response.begin()
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/http/client.py", line 319, in begin
    version, status, reason = self._read_status()
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/http/client.py", line 288, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/unittest/suite.py", line 306, in _tearDownPreviousClass
    tearDownClass()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 126, in tearDownClass
    cls.stop_process()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 114, in stop_process
    cls.cli.app_quit()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/client.py", line 31, in __call__
    response = requests.post(
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/requests/api.py", line 117, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/site-packages/requests/adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))







> app_quit: ()

TeleniumTestCase :: localy (desktop) run app :: FileNotFoundError

Description

When using TeleniumTestCase's default cmd_entrypoint value ([main.py]) we run into a problem at the following method call.

@classmethod
    def start_desktop_process(cls, cmd, env):
        cwd = os.path.dirname(cls.cmd_entrypoint[0])
        cls.process = subprocess.Popen(cmd, env=env, cwd=cwd)

Obviously, os.path.dirname returns an empty string here. As much as the user can overwrite the cmd_entrypoint value to include an absolute or relative path, the default value should work under the right circumstances. The fix is very simple, wrap the cls.cmd_entrypoint[0] argument with a os.path.abspath call — which is a pretty common practice actually. This will convert any valid path provided (including no path information at all if the file is in the cwd) into the full absolute path to the existing file.

PR on the way soon.

Various logs and file contents

main.py

import platform

import kivy

from kivy.app import App
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label


class FretboardDojo(App):
    def build(self):
        root_layout = AnchorLayout(anchor_x="center", anchor_y="center")
        widget_layout = BoxLayout(orientation="vertical", size_hint=(None, None))
        widget_layout.add_widget(Label(text='Test App'))
        widget_layout.add_widget(Label(text=f'Python {platform.python_version()}'))
        widget_layout.add_widget(Label(text=f'Kivy {kivy.__version__}'))
        root_layout.add_widget(widget_layout)
        return root_layout


if __name__ == "__main__":
    FretboardDojo().run()

buildozer.spec

[app]
title = Test App
package.name = testapp
package.domain = org.kivy
source.dir = .
source.include_exts = py,png,jpg,kv,atlas
version = 0.1
requirements = python3,kivy,zipp,more-itertools,pytz,jaraco.functools,importlib-resources,tempora,six,jaraco.text,jaraco.classes,zc.lockfile,portend,MarkupSafe,jaraco.collections,cheroot,ws4py,Werkzeug,Mako,json-rpc,CherryPy,telenium
orientation = portrait
fullscreen = 0

android.permissions = INTERNET,ACCESS_NETWORK_STATE
android.arch = armeabi-v7a

[buildozer]
log_level = 2
warn_on_root = 1

test.py

from telenium.tests import TeleniumTestCase


class TestFretboardDojo(TeleniumTestCase):
    def test_startup_screen(self):
        self.assertExists("//Label[@text~=\"Test App\"]", timeout=2)

PyCharm Console Output

/home/pdallair/anaconda3/envs/telenium/bin/python /snap/pycharm-community/261/plugins/python-ce/helpers/pycharm/_jb_unittest_runner.py --path /home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py
Testing started at 8:34 p.m. ...
Launching unittests with arguments python -m unittest /home/pdallair/dev/PycharmProjects/Telenium/TestApp/test.py in /home/pdallair/dev/PycharmProjects/Telenium/TestApp

> app_quit: ()

Failure
Traceback (most recent call last):
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/unittest/suite.py", line 166, in _handleClassSetUp
    setUpClass()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 121, in setUpClass
    cls.start_process()
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 66, in start_process
    cls.start_desktop_process(cmd=cmd, env=env)
  File "/home/pdallair/dev/PycharmProjects/Telenium/telenium/tests.py", line 87, in start_desktop_process
    cls.process = subprocess.Popen(cmd, env=env, cwd=cwd)
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/home/pdallair/anaconda3/envs/telenium/lib/python3.9/subprocess.py", line 1821, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: ''

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.