=== vrruiz_ is now known as rvr | ||
=== pgraner-afk is now known as pgraner | ||
=== chihchun is now known as chihchun_afk | ||
=== qwebirc539535 is now known as slickymasterWork | ||
svij | balloons: hey, I tried to write my first autopilot test, but I'm struggling… I tried to write a test for this bug: https://bugs.launchpad.net/ubuntu-calculator-app/+bug/1410986 But I don't know how to access the calculationHistory to do a "longpress" | 18:41 |
---|---|---|
ubot5 | Launchpad bug 1410986 in Ubuntu Calculator App "[Autopilot] Test delete multiple calculation from history" [Medium,Confirmed] | 18:41 |
balloons | svij, howdy | 18:43 |
balloons | let's have a look | 18:43 |
svij | :) | 18:44 |
=== pgraner is now known as pgraner-dr | ||
balloons | svij, so I believe step 2 is basically press and hold on the white screen at the top | 18:52 |
balloons | it will let you play with the calculations | 18:52 |
svij | balloons: yes, and I have no idea how to do that | 18:53 |
balloons | you should get an action menu and checkboxes.. | 18:53 |
balloons | ohh, lol, you mean have AP do that :p | 18:53 |
svij | yeah :D | 18:53 |
svij | sorry. :D | 18:53 |
balloons | svij,are you able to find the object ok? | 18:53 |
balloons | we can press and hold using https://developer.ubuntu.com/api/autopilot/python/1.5.0/autopilot.input.Touch/ | 18:54 |
svij | balloons: I'm not sure which object it is (I'm not really familiar with qml) | 18:55 |
balloons | svij, awesome, so let's talk about how to figure that out | 18:56 |
balloons | svij, have you tried using autopilot vis yet? Because that's how we'll figure out the object | 18:56 |
svij | hm, nope | 18:56 |
svij | let me find the docs… | 18:57 |
svij | https://developer.ubuntu.com/api/autopilot/python/1.5.0/guides-running_ap/#visualise-introspection-tree the images are broken :( | 18:58 |
balloons | svij, yikes.. we'll have to fix that! | 18:59 |
svij | (it's also broken on a couple of other pages of the autopilot pages) | 18:59 |
balloons | right, thanks for pointing it out. I'll file a bug on the site nd get it fixed | 18:59 |
balloons | anyways, so right. first lanuch the app, then run vis to have a visual look at the introspection tree | 19:01 |
balloons | for calculator I wold do this: | 19:01 |
balloons | autopilot launch -i Qt qmlscene app/ubuntu-calculator-app.qml | 19:01 |
balloons | autopilot3 vis | 19:01 |
svij | got it | 19:03 |
svij | and selected the calculator app in vis | 19:03 |
balloons | excellent. So now you can see the full tree. It's a little odd to browse at first, but you'll get used to it | 19:04 |
balloons | look under the MainView and OrientationHelper to get into the app internals | 19:05 |
svij | and then? | 19:05 |
balloons | see the yellow button next to the spyglass at the top of the app? | 19:06 |
svij | yes | 19:06 |
balloons | if you toggle it, it would highlight the part of the app that the object you select in the tree represents | 19:06 |
balloons | this can sometimes be useful | 19:06 |
balloons | so now I would try and figure out / understand what objects are in the top of the calculator | 19:06 |
balloons | looking through things, I see a PageStack, other Page definitions, and then finally a header and a scrollable view | 19:08 |
svij | the scrollview was hard to find | 19:10 |
svij | scrollable view* | 19:10 |
balloons | svij, yes, sometimes the object tree is just a little confusing. In those cases, let me show you another way to grok the tree | 19:10 |
svij | and the QQuickLoader seems to be one item of the calculation history | 19:12 |
balloons | check out print_tree() on https://developer.ubuntu.com/api/autopilot/python/1.5.0/autopilot.introspection.ProxyBase/ | 19:12 |
balloons | so one thing you can do is launch the app under test in python, then do a dump of the tree if you will to a file, using print_tree on the root node | 19:12 |
balloons | does that make sense? | 19:12 |
svij | how do I "launch the app under test in python"? | 19:13 |
balloons | svij, that's what is happening in the test cases. So in this case I would add another test case to the test_main.py file, and then have autopilot run it | 19:15 |
svij | oh right | 19:15 |
balloons | svij, something tiny, like def test_dump_tree(self): | 19:15 |
balloons | self.app.main_view.print_tree() | 19:15 |
svij | trying… | 19:16 |
balloons | make sure you redirect the output to a file when you run :-) | 19:16 |
balloons | so it doesn't dump to your console | 19:17 |
svij | hehe, yes. | 19:18 |
svij | okay, and now? | 19:19 |
balloons | we can review the output. Also, I had a look in the test helpers and noticed there is already a helper for calculationhistory | 19:20 |
balloons | do you see it in __init__.py? | 19:20 |
svij | yes | 19:20 |
balloons | I also see mainview has a helper method already called get_history | 19:22 |
svij | yes, i see | 19:22 |
balloons | if you look inside your dump, you can see this object.. Look for objectName: 'scrollableView' | 19:23 |
balloons | anyways, I might suggest that this is exactly what we want to press and hold | 19:23 |
balloons | what do you think? | 19:23 |
svij | sure | 19:23 |
svij | but do I need to press and hold that scrollableView or one item in that scrollableView? | 19:25 |
balloons | so let's try. First, use the helper method that already exists to get the object, then use autopilot to press and hold it | 19:25 |
balloons | when you interact with an object, by default autopilot will try and determine it's coordinates, then press in the middle of the object | 19:26 |
svij | ahh | 19:26 |
balloons | so that might work just fine for us | 19:26 |
svij | do I need the "press_and_hold" method from MainView in __init__.py? | 19:26 |
=== jhodapp_ is now known as jhodapp | ||
balloons | svij, no, that's a custom method and by looking at it I can see it's intended to press and hold a button on the keypad | 19:29 |
svij | oh right | 19:29 |
balloons | yea, should be more aptly named / commented | 19:29 |
svij | so, I'm getting the object with "self.app.main_view.get_history()" right? | 19:30 |
balloons | anyways, so just use autopilot methods themselves to click. | 19:31 |
balloons | svij, yes | 19:31 |
svij | so, call ".press()" on that? | 19:31 |
svij | or tap, with a duration… | 19:32 |
balloons | svij, yes but I realized that doesn't help you :-) Have a look at https://developer.ubuntu.com/api/autopilot/python/1.5.0/autopilot.input.Pointer/.. You'll see there's a nice method called click_object | 19:32 |
balloons | and move_to_object | 19:32 |
balloons | otherwise you'd have to read the object properties yourself, then press at the proper position. Easier to simply use the built-in method AP provides to do this | 19:33 |
svij | wait, how do I call that exactly? | 19:35 |
balloons | svij, so notice you'll need to creating a pointing device, and these methods are for that class. Now, if you look at the CalculatorApp class in __init__.py, you'll see we've done this in the __init__ method | 19:36 |
balloons | err sorry.. we declare a property in the class rather . . . | 19:37 |
svij | um, ok. | 19:37 |
balloons | does that make sense to you? | 19:37 |
balloons | just know you have a pointing_device ready to go you can use for this stuff under self.app.pointing_device | 19:38 |
balloons | so self.app.pointing_device.click_object, self.app.pointing_device.press, etc | 19:38 |
svij | let me check… | 19:39 |
balloons | you can learn more about the details of how the app is launched and the objects initialized can come later | 19:39 |
svij | I've got two lines in my test case right now: | 19:41 |
svij | self.app.pointing_device.move_to_object(self.app.main_view.get_history()) | 19:42 |
svij | self.app.pointing_device.click_object(self) | 19:42 |
svij | but that doesn't work | 19:42 |
svij | "ValueError: Object '<ubuntu_calculator_app.CalculationHistory object at 0x7f2368163c18>' does not have any recognised position attributes | 19:43 |
svij | oh wait… | 19:43 |
balloons | svij, just fyi the self.app.pointing_device.move_to_object isn't needed as click_object will do that for you | 19:44 |
balloons | svij, so here's what I wrote: | 19:44 |
balloons | history = self.app.main_view.get_history() | 19:44 |
balloons | self.app.pointing_device.click_object(history, 1, 3) | 19:44 |
balloons | I got the same error as you, so clearly the object we get from history isn't what is being shown :-) | 19:45 |
balloons | since it doesn't have x,y,z coords, it's an internal object. | 19:45 |
svij | okay | 19:45 |
balloons | ohh, look at the get_history method again | 19:46 |
balloons | it's returning a class | 19:47 |
svij | yes | 19:48 |
svij | so…? | 19:48 |
balloons | so, we need an object to pass to AP, not a class | 19:49 |
svij | right | 19:49 |
balloons | svij, so notice in __init__, it puts the object in self.app. So we could pass AP the object directly | 19:50 |
balloons | history.app. That runs for me, but doesn't quite do what we want | 19:51 |
svij | let me check… | 19:51 |
balloons | I hope working through it like this is helping.. I'm going through it slowly with you the same way as I would approach it | 19:51 |
svij | yeah, sure, it helps. :) | 19:51 |
svij | and yes, it doesn't really help us. | 19:53 |
svij | (i mean the code) | 19:53 |
balloons | but you now have the knowledge you need to click the object once we find it | 19:54 |
balloons | so at this point I would look deeper into scrollable view. It looks like / my guess is the history we see is laid out in rows | 19:55 |
svij | it is | 19:55 |
svij | QQuickLoaders it seems | 19:56 |
balloons | so ideally we would enter a calculation, then long press on it's history result I think | 19:57 |
balloons | or actually it's asking us to test deleting more than 1 as well | 19:57 |
svij | yes | 19:59 |
svij | but I need to figure out how to access one of those QQuickloaders | 19:59 |
balloons | svij, so one thing we can do is use strings to help get us closer to understanding the layout. I would do a print_tree again, but using the calc history object as the root this time. | 19:59 |
balloons | Then I would look for a string that is one of the numbers in the history | 20:00 |
balloons | doing that gave me an object under /comubuntucalculator/QQuickView/MainView/OrientationHelper/QQuickItem/QQuickItem/PageStack/PageWrapper/PageWithBottomEdge/ScrollableView/QQuickItem/QQuickColumn/QQuickLoader/Screen/QQuickRectangle/QQuickItem/QQuickColumn/QQuickRow/QQuickText | 20:01 |
svij | yes | 20:03 |
balloons | so at this point, it seems the layout is under Screen. I would go look at the qml and set an objectname on the object I want, if there isn't one | 20:04 |
svij | ok, let me check… | 20:05 |
svij | balloons: is "screenDelegate" as an objectName okay? | 20:07 |
balloons | svij, sure | 20:07 |
svij | good :) | 20:07 |
svij | and now? | 20:08 |
svij | I think I need to add an "_get_screen" function, which returns the screen? | 20:09 |
svij | in __init__.py | 20:09 |
balloons | svij, sure we could make a helper class with some methods again | 20:11 |
balloons | but I'd get things working first before trying to abstract things | 20:11 |
balloons | imho | 20:11 |
svij | oh, right, sure. | 20:11 |
svij | let me try… | 20:13 |
balloons | k, I'm looking at / in Screen.qml | 20:15 |
balloons | I added objectnames to the results and to the root Screen | 20:15 |
* svij thought that this is a simple autopilot test for the beginning :) | 20:15 | |
balloons | svij, it's turning a little more difficult because we don't have handy access to the objects we need | 20:16 |
balloons | but this is good learning material ;-) | 20:16 |
svij | yeah, definitely | 20:16 |
svij | isn't that documented somewhere? | 20:17 |
balloons | what documented? | 20:17 |
svij | how to find and access objects without helper functions | 20:18 |
balloons | well, that's more or less what vis and print_tree are for. But there's no magical shortcuts besides simply reading the qml | 20:19 |
svij | oh ok | 20:19 |
balloons | that said, I'm happy to hear of docs that would be helpful. Happy to write them | 20:19 |
svij | so the result text has objectName | 20:20 |
svij | but I added an objectname to the root element | 20:20 |
svij | (and I'm happy to help to improve the docs ;) ) | 20:21 |
balloons | :-) | 20:24 |
balloons | So I noticed Screen.qml uses ListItemWithActions.qml | 20:24 |
svij | yes | 20:24 |
balloons | so when I added an objectname there, I see it now :-) | 20:25 |
balloons | it's a bit odd | 20:25 |
svij | wait, where do you "see it now"? | 20:25 |
balloons | in the dbus tree dumps. I was looking for an objectname under a Screen object | 20:26 |
svij | dbus tree dump was that print_tree() command, right? | 20:27 |
balloons | svij, yes, I've been iterating over running dumps using it.. | 20:28 |
svij | ok | 20:28 |
balloons | I'm dumping with Screen as the root object | 20:28 |
balloons | note, there appears to be 2 Screen objects also | 20:29 |
balloons | so | 20:29 |
balloons | screens = self.app.main_view.select_many('Screen') | 20:29 |
balloons | for screen in screens: | 20:29 |
balloons | screen.print_tree() | 20:29 |
svij | ok | 20:31 |
balloons | so, my issue to solve at this point is figure out how to make sure I select a specific object in the list. Doing those dumps shows me there are mutliple result objects for instance.. each result is sharing the same objectname | 20:31 |
balloons | normally we would fix that by adding a dynamic property to the objectname declaration. So for example, objectName: "listitem" + index | 20:32 |
svij | and in this case (if its not 'normally')? | 20:33 |
svij | balloons: do you mind, if we continue tomorrow? It's getting late here and I'm really tired now and less concentrated… | 20:37 |
balloons | svij, well the qml object is custom it seems. So it's more painful | 20:37 |
balloons | svij, no worries. I'll figure out how to assign the objectname sanely so we can get back to the actual test | 20:37 |
svij | great! | 20:37 |
balloons | if you encounter something like this, the answer is always ask the developer | 20:37 |
balloons | what on earth is going on in your custom object :-) | 20:38 |
svij | first I need to figure out what are "normal" and what are "custom" objects | 20:38 |
svij | and how to access them properly ;) | 20:38 |
balloons | svij, "normal" is assign the objectname and then see it in the tree and go | 20:38 |
balloons | lol | 20:38 |
svij | anyway, thanks so far! I'll ping you tomorrow | 20:39 |
balloons | good night! | 20:40 |
svij | thanks | 20:41 |
balloons | yw | 20:41 |
Generated by irclog2html.py 2.7 by Marius Gedminas - find it at mg.pov.lt!