1

I have got list items with deeply neested objects/properties (I can't change that) - and several (20-50) other similar situations with other nesting

something like:

List[]
 Item
   A
     B
     C <-- "change item type"
      D
       E <-- "delete item"
   F
   G
    H <-- "change color"

using findAllObjects with a real/symbolic name i get all the occurences of Items (its in a unique typed list) and then using hasattr, object.children etc. on it to gather all needed parts

realname/object-mapping+findAll+object.children gathering ==> python object

results in an object dict like:

a[] = {{c,e,h},{c,e,h},{c,e,h},...}

that works without any problem

waitForObject(a[0].f) or mouseClick(waitForObject(a[0].i)) is then a typical usage

the problem is that some operations on my results invalidating the results itself, for example clicking the "delete item" object

my current solution is to re-read the complete list after doing any change on it because I can't easily check if an object is still valid

waitForObject does not help because some of the List items are not visible and waitForObjectExists can't handle objects as parameter to check if an invisible item is maybe invalid, objects.exists seem to only accept realname no objects

my base problem is that I sometimes do not know (due to the complexity of the software) if some operations are invalidating my beforehand gathered information and I don't want to always re-read everything that maybe depends

any ideas, strategies, best practices?

UPDATE #1: I always check for Lookup exceptions, but how to check if non-visible (python)objects are still valid (waitForExits or object.exits etc. do not allow using objects as parameter)

it sometimes happen that i do not know that something invalidates my objects - its a big app (>1Mio LOC) that i start to test with Squish, with highly dynamic QML interface (Loaders, dynamic Element adding/removal) - not very easy to track object hierarchy invaldiation, very dynamic

so my solution is: use findAllObjects + object.children hierarchy read all info i need, do a single test and re-read all data because i know that will invalidate my data, but that could happen in so many places that i just want to place some asserts around to detect if some of my objects get invalidated (without me knowing it at that time) - but that seems to not be possible with the Squish API

UPDATE #2:

i just found out that if i collect object references with waitForObject/findAllObjects etc. and do a change to the hierarchy where the referenced objects resist all my related object references getting invalidated in Python

all_items1 = findAllObjects(names.listItems)
mouseClick(names.delete_button)
all_items2 = findAllObjects(names.listItems)

all_items1 before delete_button click:

[0] MyItem_QMLTYPE... <complex object>
[1] MyItem_QMLTYPE... <complex object>
[2] MyItem_QMLTYPE... <complex object>

all_items1 after delete_button click:

[0] MyItem_QMLTYPE... <null>
[1] MyItem_QMLTYPE... <null>
[2] MyItem_QMLTYPE... <null>

all_items2:

[0] MyItem_QMLTYPE... <complex object>
[1] MyItem_QMLTYPE... <complex object>
[2] MyItem_QMLTYPE... <complex object>

so it seems that these objects are activly tracked, i though there are just data copies nothing more, is this behavior somewhere explained in detail in the Squish Docs (link?) - i just overlooked it in the documentation, are only changed objects altered?

sorry for confusing everyone who tried to help

its clear now :

i absolutely need to re-gather my objects after doing changes in my hierarchy and if i forgot to re-gather all i will get are errors due to nulled object references because its not possible to use an invalidated object-reference

llm
  • 557
  • 3
  • 15
  • Straightforward solution to your problem is to wrap object lookup (or `mouseClick`, or whatever) into `try\except` block. But it seems that you are doing something wrong, because a test should track application state on its own otherwise there will be no way to verify result, so if test deleted something then it should already know that an item is invalid and there is no point to access it. Also, it is not clear what your code should do if an object is not found, it should just re-iterate over the tree and then click on another random item? – Vader Aug 25 '19 at 22:01
  • I still don't completely understand what you are trying to achieve, but to determine if invisible object is still here you can try to access one of its properties (e.g. `objectName`, `x`) inside a `try\except` block and and re-read the tree in case of exception (I believe it should be `RuntimeError` or similar). While this naive approach should work I recommend to store real names instead of objects. You can construct real names in the same way as suggested here https://stackoverflow.com/a/57548773/735893 With real names you'll be able to use any synchronization function. – Vader Aug 26 '19 at 12:31
  • 1. "I believe it should be RuntimeError or similar..." i will re-test accessing properties of an "invalid" (deleted) object, but i think the properties are not activly connected to squish and i will just get the value, 2. i can't create realnames with x,y or other properties to get a fix real name - some of the elements moving around while testing (what is totaly ok) and i can't use special ids/object names for every wild combination – llm Aug 27 '19 at 06:35
  • in short: im challenging how to do idealy test this huge software with Squish - and how the other 10 developers will create tests - that includes: writing helper functions, classes etc. as a groundwork to reduce the amount of errors others can make while writing tests so not every test gets a research project on its own, simple things like property-access wrappers that detects if something is not visible/enabled, useable(but not visible) or invalid etc., some sort of standard functions to prevent silly bugs – llm Aug 27 '19 at 06:44
  • You can use isNull() to determine if a reference is still valid. And waitForObject() and waitForObjectExists() accept references, too, not just object names. – frog.ca Aug 31 '19 at 00:47
  • waitForObjectExists(waitForObject({"type": "QMainWindow"})) , LookupError: waitForObjectExists() requires an object name argument, waitForObject(waitForObject({"type": "QMainWindow"})) works - maybe we mix up object-names(like {"type": "QMainWindow"}) and references(result of waitForObject) – llm Sep 11 '19 at 09:25

0 Answers0