calabash/calabash-ios-server — pull request #17 by jmoody (2013-05-21 20:00:06+00:00)
Title: addes a new 'scroll to row with id' operation that allows calabash to

see https://github.com/calabash/calabash-ios/issues/128

i routinely need to scroll to a particular row and touch it. my current solution is this:

```
def scroll_until_i_see_row (dir, row_id)
query = "tableView descendant tableViewCell marked:'#{row_id}'"
wait_poll({:until_exists => query,
:timeout => 2}) do
scroll('tableView', dir)
end
# issue 128 - can i actually touch the row?
unless row_exists?(row_id)
screenshot_and_raise "i scrolled '#{dir}' but did not see '#{row_id}'"
end
end
```

this is not a good solution for a couple of reasons.

* [issue 128](see https://github.com/calabash/calabash-ios/issues/128) - there are lot's of situations where the `:until_exists` evals to `true`, but the row itself is not touchable by calabash `touch`
* the table has to be in a _just-so_ state before i call `scroll_until_i_see_row` so i know whether or not to scroll up or down

to overcome issue 128, i have tried various heuristics for applying the row touch with offsets; these work in most cases, but they are heuristics.

i have looked at `scroll_to_cell` which calls `UITableView scrollToRowAtIndexPath:atScrollPosition:animated:` to scroll to a particular row in the table. this has the very attractive side effect of always scrolling in such a way that the entire cell is visible which eliminates the navbar/tabbar problems in issue 128. however, there are several problems with `scroll_to_cell`

1. my clients don't know what, for example, _row 5_ means
2. most of the time, i don't know what _row 5_ means
3. what _row 5_ means is always changing during development
4. there is a disconnect between the indexes of _visible_ rows in a table and the indexes that are passed to `scroll_to_cell` which means i can't use it in conjunction with a query like:

```
all_vis_rows = query("tableViewCell marked:'#{row_id}'", :accessibilityIdentifer)
index = all_vis_rows.index(row_id)
```

in a nutshell, using row indexes is awkward and confusing and it makes refactoring a nightmare.

it would be better if i could scroll to a row using its `accessibilityIdentifier`. the position in the table of the `show friends` row might change during development, but the result of touching the `show friends` row is probably not going to change all that much.

in this pull request, i created a new operation `LPScrollToRowWithIdOperation` that lets the tester pass a _row identifier_. on the calabash-cucumber side, i use this new operation like this:

```
def scroll_to_row_with_id(row_id, options={:query => 'tableView',
:scroll_position => :top,
:animate => true})
uiquery = options[:query] || 'tableView'

args = []
if options.has_key?(:scroll_position)
args << options[:scroll_position]
else
args << 'top'
end
if options.has_key?(:animate)
args << options[:animate]
end
views_touched=map(uiquery, :scrollToRowWithId, row_id, *args)

if views_touched.empty? or views_touched.member? ''
screenshot_and_raise "Unable to scroll: '#{uiquery}' to: #{options}"
end
views_touched
end
```

right now the operation only checks for `accessibilityIdentifier` equality (which will only work on iOS 5.0 and above).

before i make a significant effort to tighten this up (both on the server and client sides), i want to get some feedback about it.

is this a good idea? should i proceed?

if you don't think this a good fit for calabash, i will probably end up making a category on `UITableView` to enable me to reliably scroll to rows.

thanks,

jjm