AirtestProject / Airtest

UI Automation Framework for Games and Apps
http://airtest.netease.com/
Apache License 2.0
8.17k stars 1.29k forks source link

Poco报错:TypeError: string indices must be integers #361

Open IcyW opened 5 years ago

IcyW commented 5 years ago

Remove any following parts if does not have details about

Describe the bug A clear and concise description of what the bug is. Or paste traceback below. 使用poco时报错:TypeError: string indices must be integers

Traceback (most recent call last):
  File "/anaconda3/lib/python3.7/site-packages/airtest/cli/runner.py", line 65, in runTest
    six.reraise(*sys.exc_info())
  File "/anaconda3/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/anaconda3/lib/python3.7/site-packages/airtest/cli/runner.py", line 61, in runTest
    exec(compile(code.encode("utf-8"), pyfilepath, 'exec'), self.scope)
  File "/Users/mymymy/Workspace/proj_automation/ui_airtest/tlive_app_ios/tlive_creat_plan.air/tlive_creat_plan.py", line 152, in <module>
    creatPlan.create_live_plan_video(count)
  File "/Users/XXX/Workspace/proj_automation/ui_airtest/tlive_app_ios/tlive_creat_plan.air/tlive_creat_plan.py", line 83, in create_live_plan_video
    poco("创建直播").click()
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 23, in wrapped
    return func(proxy, *args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 332, in click
    pos_in_percentage = self.get_position(focus)
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 72, in wrapped
    return func(proxy, *args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 613, in get_position
    pos = self.attr('pos')
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 39, in wrapped
    return func(self, *args, **kwargs)
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 734, in attr
    nodes = self._do_query(multiple=False)
  File "/anaconda3/lib/python3.7/site-packages/poco/proxy.py", line 872, in _do_query
    self._nodes = self.poco.agent.hierarchy.select(self.query, multiple)
  File "/anaconda3/lib/python3.7/site-packages/poco/freezeui/hierarchy.py", line 90, in select
    return self.selector.select(query, multiple)
  File "/anaconda3/lib/python3.7/site-packages/poco/sdk/Selector.py", line 78, in select
    return self.selectImpl(cond, multiple, self.getRoot(), 9999, True, True)
  File "/anaconda3/lib/python3.7/site-packages/poco/sdk/Selector.py", line 71, in getRoot
    return self.dumper.getRoot()
  File "/anaconda3/lib/python3.7/site-packages/poco/freezeui/hierarchy.py", line 35, in getRoot
    root = Node(self.dumpHierarchy())
  File "/anaconda3/lib/python3.7/site-packages/poco/drivers/ios/__init__.py", line 48, in dumpHierarchy
    data = ios_dump_json(jsonObj, self.size)
  File "/anaconda3/lib/python3.7/site-packages/poco/drivers/ios/__init__.py", line 65, in ios_dump_json
    data = json_parser(jsonObj, screen_size)
  File "/anaconda3/lib/python3.7/site-packages/poco/drivers/ios/__init__.py", line 89, in json_parser
    w = float(node["frame"]["width"])
TypeError: string indices must be integers

Expected behavior 正常运行脚本。怀疑是airtest和poco的环境配置问题,该脚本在另一台macOS上能运行成功。

python version: python3.7

airtest version: 1.0.26

You can get airtest version via pip freeze command.

Smartphone (please complete the following information):

cheliosooo commented 4 years ago

I also had this issue. Was very odd since it worked fine on one mac but didn't work on another. Nonetheless I had to go into the poco driver class to patch things up.

If anyone's still having this problem, node["frame"] is returning a string since keys are not provided in that json data for some reason, (i.e. it looks something along the lines of this: "{{34, 67}, {337, 731}}"), and since it can't parse that into json data, it has to accept it as a string.

So a quick fix I set up was to grab the values out of the string manually, (if it is a string). Go into poco/drivers/ios/__init__.py, in the json_parser() method, replace:

w = float(node["frame"]["width"])
h = float(node["frame"]["height"])
x = float(node["frame"]["x"])
y = float(node["frame"]["y"])

with this instead:

from re import search

if isinstance(node["frame"], str):
     frameData = search(r'{{(-?\d+\.?\d*), (-?\d+\.?\d*)}, {(\d+\.?\d*), (\d+\.?\d*)}}', node["frame"])
     x = float(frameData.group(1))
     y = float(frameData.group(2))
     w = float(frameData.group(3))
     h = float(frameData.group(4))
else:
     w = float(node["frame"]["width"])
     h = float(node["frame"]["height"])
     x = float(node["frame"]["x"])
     y = float(node["frame"]["y"])

Things should work fine after that.

IcyW commented 4 years ago

I also had this issue. Was very odd since it worked fine on one mac but didn't work on another. Nonetheless I had to go into the poco driver class to patch things up.

If anyone's still having this problem, node["frame"] is returning a string since keys are not provided in that json data for some reason, (i.e. it looks something along the lines of this: "{{34, 67}, {337, 731}}"), and since it can't parse that into json data, it has to accept it as a string.

So a quick fix I set up was to grab the values out of the string manually, (if it is a string). Go into poco/drivers/ios/__init__.py, in the json_parser() method, replace:

w = float(node["frame"]["width"])
h = float(node["frame"]["height"])
x = float(node["frame"]["x"])
y = float(node["frame"]["y"])

with this instead:

from re import search

if isinstance(node["frame"], str):
     frameData = search(r'{{(-?\d+\.?\d*), (-?\d+\.?\d*)}, {(\d+\.?\d*), (\d+\.?\d*)}}', node["frame"])
     x = float(frameData.group(1))
     y = float(frameData.group(2))
     w = float(frameData.group(3))
     h = float(frameData.group(4))
else:
     w = float(node["frame"]["width"])
     h = float(node["frame"]["height"])
     x = float(node["frame"]["x"])
     y = float(node["frame"]["y"])

Things should work fine after that.

It did work for me in some cases. However, another error occurred:

File "/Use  File "/Users/xxxxxx/my_airtest_project/iOS/common/login.air/login.py", line 36, in qq_login
    poco("TextField").click()
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 23, in wrapped
    return func(proxy, *args, **kwargs)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 332, in click
    pos_in_percentage = self.get_position(focus)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 72, in wrapped
    return func(proxy, *args, **kwargs)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 613, in get_position
    pos = self.attr('pos')
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 39, in wrapped
    return func(self, *args, **kwargs)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 734, in attr
    nodes = self._do_query(multiple=False)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 872, in _do_query
    self._nodes = self.poco.agent.hierarchy.select(self.query, multiple)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/freezeui/hierarchy.py", line 90, in select
    return self.selector.select(query, multiple)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/sdk/Selector.py", line 77, in select
    return self.selectImpl(cond, multiple, self.getRoot(), 9999, True, True)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/sdk/Selector.py", line 71, in getRoot
    return self.dumper.getRoot()
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/freezeui/hierarchy.py", line 35, in getRoot
    root = Node(self.dumpHierarchy())
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 49, in dumpHierarchy
    data = ios_dump_json(jsonObj, self.size)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 66, in ios_dump_json
    data = json_parser(jsonObj, screen_size)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 132, in json_parser
    child_data = json_parser(child, screen_size)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 132, in json_parser
    child_data = json_parser(child, screen_size)
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 132, in json_parser
    child_data = json_parser(child, screen_size)
  [Previous line repeated 14 more times]
  File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 96, in json_parser
    x = float(frameData.group(1))
AttributeError: 'NoneType' object has no attribute 'group'rs/xxxxxx/my_airtest_project/iOS/common/login.air/login.py", line 36, in qq_login
  poco("TextField").click()
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 23, in wrapped
  return func(proxy, *args, **kwargs)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 332, in click
  pos_in_percentage = self.get_position(focus)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 72, in wrapped
  return func(proxy, *args, **kwargs)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 613, in get_position
  pos = self.attr('pos')
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 39, in wrapped
  return func(self, *args, **kwargs)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 734, in attr
  nodes = self._do_query(multiple=False)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/proxy.py", line 872, in _do_query
  self._nodes = self.poco.agent.hierarchy.select(self.query, multiple)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/freezeui/hierarchy.py", line 90, in select
  return self.selector.select(query, multiple)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/sdk/Selector.py", line 77, in select
  return self.selectImpl(cond, multiple, self.getRoot(), 9999, True, True)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/sdk/Selector.py", line 71, in getRoot
  return self.dumper.getRoot()
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/freezeui/hierarchy.py", line 35, in getRoot
  root = Node(self.dumpHierarchy())
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 49, in dumpHierarchy
  data = ios_dump_json(jsonObj, self.size)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 66, in ios_dump_json
  data = json_parser(jsonObj, screen_size)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 132, in json_parser
  child_data = json_parser(child, screen_size)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 132, in json_parser
  child_data = json_parser(child, screen_size)
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 132, in json_parser
  child_data = json_parser(child, screen_size)
[Previous line repeated 14 more times]
File "/Users/xxx/anaconda3/envs/py36/lib/python3.6/site-packages/poco/drivers/ios/__init__.py", line 96, in json_parser
  x = float(frameData.group(1))
AttributeError: 'NoneType' object has no attribute 'group'
cheliosooo commented 4 years ago

So this means the regex is not matching in some cases. Can you add a print statement and log node["frame"] before that added code, so you can see what the frame data looks like before it runs into that error?

IcyW commented 4 years ago

I've tried to debug the program and figured out that when the errors, the structure of node is like:

image

However, if the program runs properly, it should be like: image

IcyW commented 4 years ago

I also had this issue. Was very odd since it worked fine on one mac but didn't work on another. Nonetheless I had to go into the poco driver class to patch things up.

If anyone's still having this problem, node["frame"] is returning a string since keys are not provided in that json data for some reason, (i.e. it looks something along the lines of this: "{{34, 67}, {337, 731}}"), and since it can't parse that into json data, it has to accept it as a string.

So a quick fix I set up was to grab the values out of the string manually, (if it is a string). Go into poco/drivers/ios/__init__.py, in the json_parser() method, replace:

w = float(node["frame"]["width"])
h = float(node["frame"]["height"])
x = float(node["frame"]["x"])
y = float(node["frame"]["y"])

with this instead:

from re import search

if isinstance(node["frame"], str):
     frameData = search(r'{{(-?\d+\.?\d*), (-?\d+\.?\d*)}, {(\d+\.?\d*), (\d+\.?\d*)}}', node["frame"])
     x = float(frameData.group(1))
     y = float(frameData.group(2))
     w = float(frameData.group(3))
     h = float(frameData.group(4))
else:
     w = float(node["frame"]["width"])
     h = float(node["frame"]["height"])
     x = float(node["frame"]["x"])
     y = float(node["frame"]["y"])

Things should work fine after that.

In poco/drivers/ios/__init__.py, I modified like this :

    # w = float(node["frame"]["width"])
    # h = float(node["frame"]["height"])
    # x = float(node["frame"]["x"])
    # y = float(node["frame"]["y"])

    w = float(node["rect"]["width"])
    h = float(node["rect"]["height"])
    x = float(node["rect"]["x"])
    y = float(node["rect"]["y"])

And everything became alright. ( Still confusing...

bison1994 commented 3 years ago

版本升级到最新即可 upgrade pocoui and airtest to the latest version