Moving on from UISpec

238 views
Skip to first unread message

Pete Hodgson

unread,
Oct 14, 2011, 1:54:56 PM10/14/11
to frank-...@googlegroups.com
Hi Franksters,

I'd like to talk about removing Frank's dependency on UISpec. I've been wanting to do this for a while, and I suspect others have too. UISpec was a great starting point for Frank, but I feel that we've pushed it as far as is reasonable. It seems to be a pretty much unmaintained library at this point. The implementation is.... idiosyncratic, and quite hard to work with. An example being the long timeout issue that several people have tried and failed to fix. I believe that there are now alternatives to UISpec which are simpler, fuller featured, and undergoing active forward development.

Frank uses UISpec for two different things. We use it to perform view selection via its selector syntax, and we use it to simulate interactions (touches, gestures, etc). I have been experimenting with using alternative libraries to achieve the same functionality. It appears to be pretty trivial to use KIF's UIView additions in order to simulate interactions. I've spoken with the KIF maintainers and they are very happy for Frank to use KIF's code. We're agreed that it would be a win-win for both projects. Regarding view selection, I've been working on a library called Shelley which allows view selection using the same selector syntax as UIQuery. It is a little tricky to get exact backwards compatibility because of the way that UIQuery is implemented, but I think I have a pretty good implementation at this point. It even has unit tests, ZOMG. You can see the current implementation on the shelley branch of my github repo.

Now my main concern is how to make the transition away from UISpec and towards KIF and Shelley without causing a lot of breakage for people using Frank today. I'm considering creating a branch for the legacy UISpec-based Frank which would be maintained for folks that haven't transitioned, and then make a major version release bump (to 1.0 I guess) for the new-and-improved Frank. What do folks think of this approach? Any alternate suggestions? I'm *really* open to hearing peoples opinions on this. The last thing I want to do is screw over folks who are currently using Frank. One concern I have is that individual additions that people have made based on UISpec (e.g. the web view additions that Pat has added) would have to be ported over to Frank 1.0. I think it would be very straightforward to do this, but it wouldn't be a total freebie.

Cheers,
Pete

abaca way

unread,
Oct 14, 2011, 3:04:36 PM10/14/11
to Frank
Hi Pete,
I am open to any improvement for Frank framework. I just have a few
line of codes on my local machine that need to be ported too.
The only concern I have is that the UIQueryWebView need to supporting
injecting Javascript. which I already implemented the way to click any
elements inside UIWebView. (If anyone need this , I can share)
Pete, I can ported the sutff I added for UISpec myself.

Regards,

Pat
On Oct 14, 1:54 pm, Pete Hodgson <phodg...@thoughtworks.com> wrote:
> Hi Franksters,
>
> I'd like to talk about removing Frank's dependency on UISpec. I've been
> wanting to do this for a while, and I suspect others have too. UISpec was a
> great starting point for Frank, but I feel that we've pushed it as far as is
> reasonable. It seems to be a pretty much unmaintained library at this point.
> The implementation is.... idiosyncratic, and quite hard to work with. An
> example being the long timeout issue that several people have tried and
> failed to fix. I believe that there are now alternatives to UISpec which are
> simpler, fuller featured, and undergoing active forward development.
>
> Frank uses UISpec for two different things. We use it to perform view
> selection via its selector syntax, and we use it to simulate interactions
> (touches, gestures, etc). I have been experimenting with using alternative
> libraries to achieve the same functionality. It appears to be pretty trivial
> to use KIF's UIView additions in order to simulate interactions. I've spoken
> with the KIF maintainers and they are very happy for Frank to use KIF's
> code. We're agreed that it would be a win-win for both projects. Regarding
> view selection, I've been working on a library called Shelley which allows
> view selection using the same selector syntax as UIQuery. It is a little
> tricky to get exact backwards compatibility because of the way that UIQuery
> is implemented, but I think I have a pretty good implementation at this
> point. It even has unit tests, ZOMG. You can see the current implementation
> on the shelley branch of my github
> repo<https://github.com/moredip/Frank/tree/shelley>
> .

Kra Larivain

unread,
Oct 14, 2011, 3:11:01 PM10/14/11
to frank-...@googlegroups.com
Same here, I'm all for moving away from UISpec, I definitely agree with the reasons you stated. As long as the existing scripts are mostly backward compatible, I think that's a good thing, UISpec's code kind of got me scared when I read it.

I can take care of porting the gesture stuff to KIF might actually get assigned to working on that at work when the app I'm working on launches around thanksgiving.

/kra

Pete Hodgson

unread,
Oct 14, 2011, 3:25:01 PM10/14/11
to frank-...@googlegroups.com
Regarding gestures and KIF, check out this post I made on the KIF list - http://groups.google.com/group/kif-framework/browse_thread/thread/df3f47eff9f5ac8c. As far as I can tell KIF's gesture support has some of the same problems that I've seen with the experimental gesture stuff we've been doing with Frank. I think using KIF for simulating interactions is a good way to go, but I don't think we'll get full gesture support out of it, at least not immediately.

Derek Longmuir

unread,
Oct 14, 2011, 3:35:16 PM10/14/11
to frank-...@googlegroups.com
Hi Pete,

Is it possible for the KIF/Shelly and UISpec to co-exist? That seems
less risk than a complete upgrade and we could migrate the step
definitions over as we go along.

If they can't co-exist (or maybe as an alternative to keep things more
separated), how much effort would it be to provide 2 static libraries
and switch at the step/ruby level (plus having the right library
linked in)?

I'm trying to judge the maintenance costs of having two separate
branches vs. a single one that has some shelly/kif feature branches in
it. It feels to me like staying in one branch is less risky too.

Derek.

Rodney Degracia

unread,
Oct 14, 2011, 4:01:45 PM10/14/11
to frank-...@googlegroups.com


Pete,

I agree that creating a branch for the legacy version of Frank, is the way to go.  

The benefits are obvious:

a) we can start work on a new version of Frank  without affecting those (like myself) who still have projects that use the older branch. 

b) as we start new Xcode projects, we can start to use the newer Frank master branch




Rodney Degracia




Stewart Gleadow

unread,
Oct 16, 2011, 7:18:12 PM10/16/11
to frank-...@googlegroups.com
I like this move. I was using KIF the other day thinking the perfect solution would be KIFs interaction support, but being able to write tests in Cucumber not Objective C...

If you want to look at another example of view introspection, DCIntrospect (https://github.com/domesticcatsoftware/DCIntrospect) seems to be pretty solid and gaining popularity (although it's used for manual introspection, not automated testing). You get quite a lot of info about each view.

- Stew

Dale Emery

unread,
Nov 1, 2011, 3:37:41 AM11/1/11
to frank-...@googlegroups.com
A possible alternative: Add a new Frankly verb to map with Shelley queries, and continue to use UISpec for the existing verb.

A big advantage: It frees you to make Shelley into what you want it to be, instead of what UISpec was.

Most of the map command can be common. The only difference is which query engine you call.

Dale

Peter Hodgson

unread,
Nov 1, 2011, 11:04:45 AM11/1/11
to frank-...@googlegroups.com
Good thoughts, thanks Dale. I did consider taking this opportunity to create a brand new selector syntax, possibly something more formalized or structured. I decided against it, at least for now. The main goal for Shelley is to remove Frank's dependency on UISpec. We can't cut the cord on UISpec unless existing Frank users have a clear and easy migration path.

I do like the idea of being able to specify a selector engine - kinda like choosing between XPath or CSS when doing web testing. Maybe we should extend the map command to do that as part of the Selley migration, rather than adding a brand new command. As you point out, most of the command would be shared.

Cheers,
Pete

Dale Emery

unread,
Nov 1, 2011, 4:41:41 PM11/1/11
to frank-...@googlegroups.com
Hi Pete,


Good thoughts, thanks Dale. I did consider taking this opportunity to create a brand new selector syntax, possibly something more formalized or structured. I decided against it, at least for now. The main goal for Shelley is to remove Frank's dependency on UISpec. We can't cut the cord on UISpec unless existing Frank users have a clear and easy migration path.

Ah, I see.
 
I do like the idea of being able to specify a selector engine - kinda like choosing between XPath or CSS when doing web testing. Maybe we should extend the map command to do that as part of the Shelley migration, rather than adding a brand new command. As you point out, most of the command would be shared.

Do you mean that I could plug in whatever selector engine I want? I'd like that.

As I look over the Shelley code, I notice some quirks that I might have trouble explaining to my client (I can explain if you like, or shut the hell up if you like). Given your goal of maintaining compatibility with UIQuery syntax, I suspect you would (quite reasonably) be less open to my ideas for "improving" the syntax. But if I could plug in my own engine...

If I can help with this, let me know. I'm a complete noob with Objective-C, but from reading your nice, clean code I'd bet that my OO experience would allow me to contribute quickly.

Dale

Peter Hodgson

unread,
Nov 1, 2011, 7:05:17 PM11/1/11
to frank-...@googlegroups.com
One area I definitely am looking for input on is what this hypothetical selector syntax would look like. Something css-like would possibly lower the barrier to entry. Something xPath like would be quite terrifying for a lot of people, but could lend itself to more advanced stuff like selecting parents, siblings and cousins (something that css is lacking I think).

Does anyone have any good examples on any other similar syntaxes other than css and XPath that might serve as inspiration?

Also, Dale, would be interested to hear what quirks you're noticing in Shelley. If they're for backwards compatibility then so be it, but if not then I'd like to know so I can fix 'em :)

Dale Emery

unread,
Nov 1, 2011, 9:30:52 PM11/1/11
to frank-...@googlegroups.com
Hi Pete,

One area I definitely am looking for input on is what this hypothetical selector syntax would look like. Something css-like would possibly lower the barrier to entry. Something xPath like would be quite terrifying for a lot of people, but could lend itself to more advanced stuff like selecting parents, siblings and cousins (something that css is lacking I think).

I've been fiddling with an idea today. I'll include it below the signature, if I can stop fiddling with the darned thing.

Does anyone have any good examples on any other similar syntaxes other than css and XPath that might serve as inspiration?

It hadn't occurred to me to model off of css. I'll take a look at that and see what ideas emerge.

Also, Dale, would be interested to hear what quirks you're noticing in Shelley. If they're for backwards compatibility then so be it, but if not then I'd like to know so I can fix 'em :)

I'll write those in a separate message (maybe a separate thread).

Dale

--
Dale Emery
Consultant to software teams and leaders


Igor Selector Syntax

I call it Igor because it gathers stuff to be operated on by Frank
(Frank the doctor, not his pitiful, misunderstood creation).

It may or may not be an acronym for iPhone Graphical Object Retriever.


QUERIES, STEPS, and PARTS

A query is a sequence of query steps. It looks like this:
[step] [step] [step]

The whitespace is optional.

Each query step gathers a set of views, filters them, and passes the
selected views on to the next step.

Each step receives the list of views selected by previous steps,
gathers a new set of views based on tree-relationships with the
previously selected views, then submits the newly gathered views
to three kinds of filters (list filters, class filters, and
instance filters).

A step has four parts:
- one gatherer that gathers views from the containment tree.
- one list filter that select views based on their position in the list of gathered views.
- one class filter that selects views based on their class.
- one or more instance filters that select views based on properties and method calls.

Parts may appear in any order, though some orders may read strangely.

Parts are separated by one or more whitespace characters.

Example step, with all the parts:
[first sibling class isa:UIButtonView property text:'My Button']
- Gatherer: siblings
- List Filter: first
- Class Filter: class isa:UIButtonView
- Instance Filter: property text:'My Button'


GATHERERS

A gatherer gathers views based on some tree relationship with a given view.

[self] is the view currently being considered (each view gathered from previous steps)
[ancestor|ancestors from:min to:max]
- gathers views that contain self
- default range is from:1 to:last
- the range selects from the list of views from self to outermost view
- from:0 includes self
[descendant|descendants from:min to:max]
- gathers views contained within self
- default range is from:1 to:last
- the range selects from the list of views along each path from self to a leaf
- from:0 includes self
[cousin|cousins distance:distance]
- gathers views that share a common ancestor with self, and that are the same
 distance from common ancestor as self is
- default distance is distance:1, which means first cousin

Shorthands:
[self] is equivalent to [ancestor from:0 to:0] and [descendants from:0 to:0]
[parent] is equivalent to [ancestor from:1 to:1]
[child|children] is equivalent to [descendant from:1 to:1]
[sibling|siblings] is equivalent to [cousin distance:0]

(For siblings, may also want preceding-siblings and following-siblings)


FILTERS

A filter selects from the views gathered within the current step.

List filters:
[all]
[first]
[last]
[index:i] or [i] (negative means from end)
[range from:min to:max] aka [from:min to:max] (default from:0 to:last)

Class filters:
[class is:name] (possible shorthand: class:name or classIs:name)
[class isa:name] (possible shorthand: isa:name)
[respondsTo:methodSignature]
[implements:interface|protocol]

Instance filters:
[property name:value] (possible shorthand: name=value)
[predicate param:arg param:arg param:arg ...]
[exists] (always true for any gathered view)

Perhaps include instance filters for common properties (i.e. marked:'mark').
But maybe leave these for drivers to implement.

Arguments:
Names and values may be 'single quoted' or "double quoted".


PARTS OF A STEP


Defaults:
- Gatherer: The default is self. So by default all of the previous step's
 result views will be gathered and passed to the filters.
- List: The default is all. So by default every view will survive the list
 filter.
- Class Filter: The default is isa:UIView. So by default every view will
 survive the class filter.
- Instance Filters: The default list of instance filters contains a single
 exists filter, which always returns true. So by default, every view will
 survive the list of instance filters.

Given the defaults, an empty step [] is equivalent to [all self isa:UIView exists]
- That is: all previously selected views that exist and are of type UIView
- That is: all results from the previous step


EXAMPLES

[class isa:UIButtonView][cousin class is:UITextField]
   - Find all text fields that are cousins of button views.

[view marked:'Fred'][child isa:'UIButtonView'][first child]
   - The first child of each button that is a child of 'Fred'.


WEIRDNESS

Applying list filters to trees is weird. What does [first descendant from:3 to:5] mean?
Maybe [descendants] returns a list, but a list filter within a [descendants] step operates on each leg of the tree.

Dale Emery

unread,
Nov 3, 2011, 11:56:04 PM11/3/11
to frank-...@googlegroups.com
Okay, I think I'm going to abandon this syntax. I've taken a peek at CSS, and I think I can map most of the concepts onto views with only a little stretching. I'll post that in another thread.

By the way, the CSS4 spec (under development) has a way to select parents and other ancestors. You add a $ to the chunk that you want to mark as the subject of the selector. Compare:

   x y means select each y that has an ancestor x.
   $x y means select each x that has a descendant y.


Dale

Jon Wingfield

unread,
Dec 6, 2011, 12:02:17 AM12/6/11
to Frank
I think this is a great idea. KIF may give the benefit of also being
faster.

How is progress on the Shelly branch going? Is this something that's
mature enough that I could start playing around with it and looking at
migrating? It seems that the API (e.g. frank_helper) should be able
to stay the same, no?

- Jon

On Oct 14, 12:54 pm, Pete Hodgson <phodg...@thoughtworks.com> wrote:
> Hi Franksters,
>
> I'd like to talk about removing Frank's dependency on UISpec. I've been
> wanting to do this for a while, and I suspect others have too. UISpec was a
> great starting point for Frank, but I feel that we've pushed it as far as is
> reasonable. It seems to be a pretty much unmaintained library at this point.
> The implementation is.... idiosyncratic, and quite hard to work with. An
> example being the long timeout issue that several people have tried and
> failed to fix. I believe that there are now alternatives to UISpec which are
> simpler, fuller featured, and undergoing active forward development.
>
> Frank uses UISpec for two different things. We use it to perform view
> selection via its selector syntax, and we use it to simulate interactions
> (touches, gestures, etc). I have been experimenting with using alternative
> libraries to achieve the same functionality. It appears to be pretty trivial
> to use KIF's UIView additions in order to simulate interactions. I've spoken
> with the KIF maintainers and they are very happy for Frank to use KIF's
> code. We're agreed that it would be a win-win for both projects. Regarding
> view selection, I've been working on a library called Shelley which allows
> view selection using the same selector syntax as UIQuery. It is a little
> tricky to get exact backwards compatibility because of the way that UIQuery
> is implemented, but I think I have a pretty good implementation at this
> point. It even has unit tests, ZOMG. You can see the current implementation
> on the shelley branch of my github

> repo<https://github.com/moredip/Frank/tree/shelley>

Peter Hodgson

unread,
Dec 6, 2011, 1:17:35 PM12/6/11
to frank-...@googlegroups.com
Shelley is ready to try out today. In fact I'd encourage you do to so. It should be a simple matter of upgrading to the latest frank code and then adding the following to your cucumber env.rb file:
   Frank::Cucumber::FrankHelper.use_shelley_from_now_on
As you said, no other changes are needed since Shelley strives for backwards compatibility with UIQuery.
Reply all
Reply to author
Forward
0 new messages