This PR introduces searchItem method which allow the client to find and get every (almost complete) path in the Qt tree leading to a specific item (searched by objectName/id as Spix already does).
It is used like thise :
s.searchItem("mainWindow/<searched item>")
Here is an example from the RemoteCtrl example :
Use Cases
I'm well aware that Spix doesn't require a full path to an item to interact with it, yet searchItem can have many other use cases.
I personally use it mainly in two ways but I'm sure one can find many others !
In the case of complex/big apps the QML code/files can be really huge and scattered, it's not always easy to find the specific object your trying to interact with nor proving it's ID is unique (because of own defined QML objects which are re-used at many places). In that case searchItem provides a huge help for finding the path to the interesting object, it can also be coupled with filters on the client side (implemented in python then) to be even more effective. It's actually a great time-saver while writing tests.
For a unit test it can be used as a logging tool, this use case has to be improve in my opinion. Currently, I use it to log the accessible items in a ComboBox in the case the test doesn't pass. But I can see that this use can be extended in different manners to other widgets
I hope you'll see how this method can be integrated in the current Spix toolkit !
DISCLAIMER
First, Spix is designed to handle partial paths to an item. Thus, if Spix find an item whose objectName matches the current searched item in the path, it strips the given path from that objectName and doing so won't search for other item which could match this objectName too.
Here is an example to illustrate the process:
Complete path: mainWindow/tooCommonObjectName/myItem
Qt Tree:
mainWindow
|__ some item
|__ button1
|__ tooCommonObjectName
|__ nothing interessant here
|__ some other item
|__ tooCommonObjectName
|__ myItem
Spix calls itemAtPath('mainWindow/tooCommonObjectName/myItem') which calls getQQuickItemAtPath('mainWindow/..') which itself calls getQQuickItemWithRoot('tooCommonObjectName/myItem', ...)
Now let's suppose the next call is FindChildItem('tooCommonObjectName', ...), because this function use depth-first tree searching it will get to that item :
mainWindow
|__ some item
|__ button1
|__ tooCommonObjectName
...and return it, then in the previous scope (getQQuickItemWithRoot) a subItem is found and the method recursively calls itself stripping the objectName tooCommonObjectName from the path.
However, knowing the full tree I drew above, we know that this first occurence of tooCommonObjectName isn't the right path to myItem. In such a case Spix won't find a path to myItem despite the fact that it exists.
The problem I highlight here isn't the fact that Spix will strip tooCommonObjectName without searching for other occurence, nor the fact that FindChildItem uses depth-first tree search.
It's just that paths containing too common object names present a risk that a test crash while it shouldn't.
Knowing that, one should just avoid to copy/paste the complete path returned by searchItem into its test unit, because too complete path aren't robust against design changes, neither are paths containing too common objectName/ID (which aren't always unique because of the reusing of own defined Qt/QML items.
The second important point is that searchItem doesn't take in account the possibility of accessing an item stored as property of another (introduces by PR #2) but I didn't see this feature used in the examples so I figured that it wasn't a big deal.
Feedback
This is a first version of this method, I would greatly appreciate any help/remark you could make about the feature in itself as well as the implementation !
This PR introduces
searchItem
method which allow the client to find and get every (almost complete) path in the Qt tree leading to a specific item (searched by objectName/id as Spix already does). It is used like thise :s.searchItem("mainWindow/<searched item>")
Here is an example from the RemoteCtrl example :
Use Cases
I'm well aware that Spix doesn't require a full path to an item to interact with it, yet searchItem can have many other use cases. I personally use it mainly in two ways but I'm sure one can find many others !
searchItem
provides a huge help for finding the path to the interesting object, it can also be coupled with filters on the client side (implemented in python then) to be even more effective. It's actually a great time-saver while writing tests.For a unit test it can be used as a logging tool, this use case has to be improve in my opinion. Currently, I use it to log the accessible items in a ComboBox in the case the test doesn't pass. But I can see that this use can be extended in different manners to other widgets
I hope you'll see how this method can be integrated in the current Spix toolkit !
DISCLAIMER
First, Spix is designed to handle partial paths to an item. Thus, if Spix find an item whose objectName matches the current searched item in the path, it strips the given path from that objectName and doing so won't search for other item which could match this objectName too. Here is an example to illustrate the process:
Spix calls
itemAtPath('mainWindow/tooCommonObjectName/myItem')
which callsgetQQuickItemAtPath('mainWindow/..')
which itself callsgetQQuickItemWithRoot('tooCommonObjectName/myItem', ...)
Now let's suppose the next call isFindChildItem('tooCommonObjectName', ...)
, because this function use depth-first tree searching it will get to that item :...and return it, then in the previous scope (
getQQuickItemWithRoot
) asubItem
is found and the method recursively calls itself stripping the objectNametooCommonObjectName
from thepath
. However, knowing the full tree I drew above, we know that this first occurence oftooCommonObjectName
isn't the right path tomyItem
. In such a case Spix won't find a path tomyItem
despite the fact that it exists.The problem I highlight here isn't the fact that Spix will strip
tooCommonObjectName
without searching for other occurence, nor the fact thatFindChildItem
uses depth-first tree search. It's just that paths containing too common object names present a risk that a test crash while it shouldn't. Knowing that, one should just avoid to copy/paste the complete path returned bysearchItem
into its test unit, because too complete path aren't robust against design changes, neither are paths containing too common objectName/ID (which aren't always unique because of the reusing of own defined Qt/QML items.The second important point is that
searchItem
doesn't take in account the possibility of accessing an item stored as property of another (introduces by PR #2) but I didn't see this feature used in the examples so I figured that it wasn't a big deal.Feedback
This is a first version of this method, I would greatly appreciate any help/remark you could make about the feature in itself as well as the implementation !