Module: Briar::Table

Defined in:
lib/briar/table.rb

Overview

noinspection ALL

Instance Method Summary collapse

Instance Method Details

#briar_scroll_to_row(row_id, table_id = nil) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/briar/table.rb', line 135

def briar_scroll_to_row (row_id, table_id=nil)
  unless table_id.nil?
    should_see_table table_id
  end

  query_str = query_str_for_table table_id

  msg = "could find row marked '#{row_id}' in table '#{query_str}'"
  options = {:query => query_str,
             :scroll_position => :middle,
             :animate => true,
             :failed_message => msg}
  scroll_to_row_with_mark row_id, options
  # you will be tempted to remove this pause - don't.
  # set :animate => false instead
  step_pause
end

#briar_scroll_to_row_and_touch(row_id, opts = {}) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/briar/table.rb', line 153

def briar_scroll_to_row_and_touch (row_id, opts={})
  if (not opts.is_a?(Hash)) and (not opts.nil?)
    _deprecated('0.1.3',
                "you should no longer pass a view_id '#{opts}' as an arg, pass opts hash instead",
                :warn)
    opts = {:wait_for_id => opts}
  end

  default_opts = {:wait_for_id => nil,
                  :table_id => nil,
                  :timeout => BRIAR_WAIT_TIMEOUT}
  opts = default_opts.merge(opts)
  table_id = opts[:table_id]
  wait_for_id = opts[:wait_for_id]
  timeout = opts[:timeout]
  briar_scroll_to_row(row_id, table_id)
  if wait_for_id.nil?
    touch_row row_id
  else
    touch_row_and_wait_to_see row_id, wait_for_id, {:timeout => timeout,
                                                    :table_id => table_id}
  end
end

#delete_row_with_edit_mode_delete_button(row_id, table_id = nil) ⇒ Object



396
397
398
399
400
401
402
# File 'lib/briar/table.rb', line 396

def delete_row_with_edit_mode_delete_button (row_id, table_id=nil)
  touch_edit_mode_delete_button row_id, table_id
  2.times { step_pause }
  touch_delete_confirmation row_id, table_id
  2.times { step_pause }
  should_not_see_row row_id, table_id
end

#edit_mode_delete_button_exists?(row_id, table_id = nil) ⇒ Boolean

Returns:

  • (Boolean)


284
285
286
287
288
# File 'lib/briar/table.rb', line 284

def edit_mode_delete_button_exists? (row_id, table_id=nil)
  query_str = query_str_for_row row_id, table_id
  # note the extra space on the Delete
  !query("#{query_str} descendant tableViewCellEditControl marked:'Delete '").empty?
end

#query_str_for_confirm_delete_in_row(row_id, table_id = nil) ⇒ Object



257
258
259
260
261
262
263
264
# File 'lib/briar/table.rb', line 257

def query_str_for_confirm_delete_in_row(row_id, table_id=nil)
  if ios5?
    # it is not either of those...
    pending 'cannot detect the confirm delete button (yet) in iOS 5'
  end
  mark = ios7? ? 'Delete' : 'Confirm Deletion'
  "#{query_str_for_row row_id, table_id} descendant control marked:'#{mark}'"
end

#query_str_for_label_and_text_exists(row_id, label_id, table_id = nil) ⇒ Object



87
88
89
90
# File 'lib/briar/table.rb', line 87

def query_str_for_label_and_text_exists (row_id, label_id, table_id = nil)
  query_str = query_str_for_row_content row_id, table_id
  "#{query_str} label marked:'#{label_id}'"
end

#query_str_for_row(row_id, table_id = nil) ⇒ Object



12
13
14
15
16
# File 'lib/briar/table.rb', line 12

def query_str_for_row (row_id, table_id = nil)
  table_id == nil ?
        "tableViewCell marked:'#{row_id}'" :
        "tableView marked:'#{table_id}' descendant tableViewCell marked:'#{row_id}'"
end

#query_str_for_row_content(row_id, table_id = nil) ⇒ Object



7
8
9
10
# File 'lib/briar/table.rb', line 7

def query_str_for_row_content (row_id, table_id = nil)
  base = query_str_for_row row_id, table_id
  "#{base} descendant"
end

#query_str_for_rows(table_id = nil) ⇒ Object



18
19
20
21
22
# File 'lib/briar/table.rb', line 18

def query_str_for_rows (table_id = nil)
  table_id == nil ?
        'tableViewCell' :
        "tableView marked:'#{table_id}' descendant tableViewCell"
end

#query_str_for_table(table_id = nil) ⇒ Object



24
25
26
27
28
# File 'lib/briar/table.rb', line 24

def query_str_for_table (table_id = nil)
  table_id == nil ?
        'tableView' :
        "tableView marked:'#{table_id}'"
end

#reorder_button_exists?(row_id, table_id = nil) ⇒ Boolean

Returns:

  • (Boolean)


302
303
304
305
# File 'lib/briar/table.rb', line 302

def reorder_button_exists? (row_id, table_id=nil)
  query_str = query_str_for_row row_id, table_id
  !query("#{query_str} descendant tableViewCellReorderControl").empty?
end

#row_visible?(row_id, table_id = nil) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/briar/table.rb', line 30

def row_visible? (row_id, table_id = nil)
  query_str = query_str_for_row row_id, table_id
  !query(query_str, AI).empty?

  #query_str = query_str_row_in_table row_id, table_id
  #exists = !query(query_str, AI).empty?
  ## if row cannot be found just return false
  #return false unless exists
  #
  #all_rows = query(query_str_rows_in_table(table_id), AI)
  #index = all_rows.index(row_id)
  #
  ## problems only happen if we are dealing with the first or last index
  #return exists if index != 0 and  index != (all_rows.length - 1)
  #
  #if index == 0 or index == (all_rows.length - 1)
  #  # collect information about the table, row, and content offset
  #  content_offset_y = query('tableView', :contentOffset).first['Y']
  #  frame = query(query_str).first['frame']
  #  cell_h = frame['height'].to_f
  #  cell_y = frame['y'].to_f
  #  table_h = query(query_str_table(table_id)).first['frame']['height']
  #
  #  # if the row is the first row and there has been no scrolling, just return true
  #  return true if index == 0 and content_offset_y == 0
  #  # if the row is the first row and more than half of it is visible
  #  return (content_offset_y + cell_y + (cell_h/2.0))/content_offset_y >= 2.0 if index == 0
  #  # if the row is the last row and more than half of it is visible
  #  return (table_h - (cell_y - content_offset_y))/(cell_h/2.0) >= 1.0 if index == (all_rows.length - 1)
  #end
end

#row_with_label_and_text_exists?(row_id, label_id, text, table_id = nil) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
96
# File 'lib/briar/table.rb', line 92

def row_with_label_and_text_exists? (row_id, label_id, text, table_id = nil)
  should_see_row row_id
  arr = query(query_str_for_label_and_text_exists(row_id, label_id, table_id), :text)
  (arr.length == 1) and (arr.first.eql? text)
end

#should_not_see_delete_confirmation_in_row(row_id, table_id = nil) ⇒ Object



250
251
252
253
254
255
# File 'lib/briar/table.rb', line 250

def should_not_see_delete_confirmation_in_row(row_id, table_id=nil)
  query_str = query_str_for_row row_id, table_id
  unless query("#{query_str} descendant tableViewCellDeleteConfirmationControl").empty?
    screenshot_and_raise "should see a delete confirmation button on row #{row_id}"
  end
end

#should_not_see_edit_mode_delete_button(row_id, table_id = nil) ⇒ Object



296
297
298
299
300
# File 'lib/briar/table.rb', line 296

def should_not_see_edit_mode_delete_button (row_id, table_id=nil)
  if edit_mode_delete_button_exists? row_id, table_id
    screenshot_and_raise "i should not see an edit mode delete button on row #{row_id}"
  end
end

#should_not_see_reorder_button(row_id, table_id = nil) ⇒ Object



313
314
315
316
317
# File 'lib/briar/table.rb', line 313

def should_not_see_reorder_button (row_id, table_id=nil)
  if reorder_button_exists? row_id, table_id
    screenshot_and_raise "i should not see reorder button on row #{row_id}"
  end
end

#should_not_see_row(row_id, table_id = nil) ⇒ Object



66
67
68
69
70
# File 'lib/briar/table.rb', line 66

def should_not_see_row(row_id, table_id=nil)
  if row_visible? row_id, table_id
    screenshot_and_raise "i should not have seen row named #{row_id}"
  end
end

#should_not_see_table(table_name) ⇒ Object



231
232
233
234
235
236
# File 'lib/briar/table.rb', line 231

def should_not_see_table (table_name)
  res = table_exists? table_name
  if res
    screenshot_and_raise "expected not to find table with access id #{table_name}"
  end
end

#should_see_delete_confirmation_in_row(row_id, table_id = nil) ⇒ Object



266
267
268
269
270
271
272
273
274
275
276
# File 'lib/briar/table.rb', line 266

def should_see_delete_confirmation_in_row(row_id, table_id=nil)
  query_str = query_str_for_confirm_delete_in_row(row_id, table_id)
  timeout = 5
  msg = "waited for '#{timeout}' seconds but did not see 'Delete' confirmation in row '#{row_id}'"
  wait_for(:timeout => timeout,
           :retry_frequency => BRIAR_WAIT_RETRY_FREQ,
           :post_timeout => BRIAR_WAIT_STEP_PAUSE,
           :timeout_message => msg) do
    element_exists query_str
  end
end

#should_see_disclosure_chevron_in_row(row_id, table_id = nil) ⇒ Object



445
446
447
448
449
450
451
452
453
# File 'lib/briar/table.rb', line 445

def should_see_disclosure_chevron_in_row (row_id, table_id=nil)
  should_see_row row_id, table_id
  # gray disclosure chevron is accessory type 1
  query_str = query_str_for_row row_id, table_id
  res = query(query_str, :accessoryType).first
  unless res == 1
    screenshot_and_raise "expected to see disclosure chevron in row '#{row_id}' but found '#{res}'"
  end
end

#should_see_edit_mode_delete_button(row_id, table_id = nil) ⇒ Object



290
291
292
293
294
# File 'lib/briar/table.rb', line 290

def should_see_edit_mode_delete_button (row_id, table_id=nil)
  unless edit_mode_delete_button_exists? row_id, table_id
    screenshot_and_raise "should see a edit mode delete button on row #{row_id}"
  end
end

#should_see_reorder_button(row_id, table_id = nil) ⇒ Object



307
308
309
310
311
# File 'lib/briar/table.rb', line 307

def should_see_reorder_button (row_id, table_id=nil)
  unless reorder_button_exists? row_id, table_id
    screenshot_and_raise "i should be able to see reorder button on row #{row_id}"
  end
end

#should_see_row(row_id, table_id = nil) ⇒ Object



62
63
64
# File 'lib/briar/table.rb', line 62

def should_see_row (row_id, table_id = nil)
  wait_for_row(row_id, {:table_id => table_id})
end

#should_see_row_at_index(row_id, index, table_id = nil) ⇒ Object



319
320
321
322
323
324
325
# File 'lib/briar/table.rb', line 319

def should_see_row_at_index (row_id, index, table_id=nil)
  query_str = query_str_for_rows table_id
  res = query(query_str, AI)[index.to_i]
  unless res.eql? row_id
    screenshot_and_raise "i should see '#{row_id}' at #{index} in '#{query_str}', but found #{res}"
  end
end

#should_see_row_with_image(row_id, image_id, table_id = nil) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/briar/table.rb', line 122

def should_see_row_with_image (row_id, image_id, table_id = nil)
  should_see_row row_id, table_id
  query_str = query_str_for_row_content row_id, table_id
  if query("#{query_str} imageView marked:'#{image_id}'").empty?
    if table_id == nil
      screenshot_and_raise "expected to see row '#{row_id}' with image view '#{image_id}'"
    else
      screenshot_and_raise "expected to see row '#{row_id}' with image view '#{image_id}' in table '#{table_id}'"
    end
  end
end

#should_see_row_with_label_that_has_no_text(row_id, label_id) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/briar/table.rb', line 107

def should_see_row_with_label_that_has_no_text(row_id, label_id)
  wait_for_row row_id
  qstr = "#{query_str_for_row_content row_id} label marked:'#{label_id}'"
  res = query(qstr, :text)
  if res.empty?
    screenshot_and_raise "expected to see row '#{row_id}' with label '#{label_id}'"
  end

  text = res.first
  unless text.nil? or text.eql?('')
    screenshot_and_raise "expected to see no text in row '#{row_id}' in label '#{label_id}' but found '#{text}'"
  end
end

#should_see_row_with_label_with_text(row_id, label_id, text, table_id = nil) ⇒ Object



98
99
100
101
102
103
104
105
# File 'lib/briar/table.rb', line 98

def should_see_row_with_label_with_text (row_id, label_id, text, table_id=nil)
  should_see_row row_id, table_id
  unless row_with_label_and_text_exists? row_id, label_id, text, table_id
    query_str = query_str_for_row_content row_id, table_id
    actual = query("#{query_str} label marked:'#{label_id}'", :text).first
    screenshot_and_raise "expected to see row '#{row_id}' with label '#{label_id}' that has text '#{text}', but found '#{actual}'"
  end
end

#should_see_slider_in_row(slider_id, row_id, table_id) ⇒ Object



455
456
457
458
459
460
461
# File 'lib/briar/table.rb', line 455

def should_see_slider_in_row (slider_id, row_id, table_id)
  query_str = query_str_for_row_content row_id, table_id
  actual_id = query("#{query_str} slider marked:'#{slider_id}'", AI).first
  unless actual_id.eql? row_id
    screenshot_and_raise "expected to see slider '#{slider_id}' in '#{row_id}' but found '#{actual_id}'"
  end
end

#should_see_slider_in_row_with_value(slider_id, row_id, value, table_id = nil) ⇒ Object



463
464
465
466
467
468
469
# File 'lib/briar/table.rb', line 463

def should_see_slider_in_row_with_value (slider_id, row_id, value, table_id=nil)
  query_str = query_str_for_row_content row_id, table_id
  actual_value = query("#{query_str} slider marked:'#{slider_id}'", :value).first.to_i
  unless actual_value == value.to_i
    screenshot_and_raise "expected to see slider '#{slider_id}' with '#{value}' in '#{row_id}' but found '#{actual_value}'"
  end
end

#should_see_switch_in_row_with_state(switch_id, row_id, state, opts = {}) ⇒ Object



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/briar/table.rb', line 334

def should_see_switch_in_row_with_state (switch_id, row_id, state, opts={})

  if (not opts.is_a?(Hash)) and (not opts.nil?)
    _deprecated('0.1.1',
               "you should no longer pass a table_id '#{opts}' as an arg, pass opts hash instead",
               :warn)
    opts = {:table_id => opts}
  end

  default_opts = {:table_id => nil,
                  :switch_class => nil,
                  :switch_state_selector => :isOn}

  opts = default_opts.merge(opts)

  table_id = opts[:table_id]

  should_see_row row_id, table_id
  row_content_qstr = query_str_for_row_content row_id, table_id

  switch_class = opts[:switch_class]
  if switch_class.nil?
    switch_qstr = "switch marked:'#{switch_id}'"
  else
    switch_qstr = "view:'#{switch_class}' marked:'#{switch_id}'"
  end

  qstr = "#{row_content_qstr} #{switch_qstr}"
  res = query(qstr, opts[:switch_state_selector]).first
  unless res
    screenshot_and_raise "expected to find a switch marked '#{switch_id}' in row '#{row_id}'"
  end
  unless res.to_i == state
    screenshot_and_raise "expected to find a switch marked '#{switch_id}' in row '#{row_id}' that is '#{state ? 'on' : 'off'}' but found it was '#{res ? 'on' : 'off'}'"
  end
end

#should_see_table(table_name) ⇒ Object



224
225
226
227
228
229
# File 'lib/briar/table.rb', line 224

def should_see_table (table_name)
  res = table_exists? table_name
  unless res
    screenshot_and_raise "could not find table with access id #{table_name}"
  end
end

#should_see_text_field_in_row_with_text(row_id, text_field_id, text, table_id = nil) ⇒ Object



387
388
389
390
391
392
393
394
# File 'lib/briar/table.rb', line 387

def should_see_text_field_in_row_with_text (row_id, text_field_id, text, table_id=nil)
  should_see_row row_id, table_id
  query_str = "#{query_str_for_row_content row_id, table_id} textField marked:'#{text_field_id}'"
  res = query(query_str)
  screenshot_and_raise "expected to see text field in '#{row_id}' row" if res.empty?
  actual = query(query_str, :text).first
  screenshot_and_raise "expected to find text field with '#{text}' in row '#{row_id}' but found '#{actual}'" if !text.eql? actual
end

#swipe_on_row(dir, row_id, table_id = nil) ⇒ Object



238
239
240
241
242
243
244
245
246
247
# File 'lib/briar/table.rb', line 238

def swipe_on_row (dir, row_id, table_id=nil)
  if (ios7? || ios8?) and simulator?
    pending('Apple bug on iOS > 6 Simulators - swiping does not work.')
  end
  wait_for_row row_id, {:table_id => table_id}
  query_str = query_str_for_row row_id, table_id
  swipe(dir, {:query => query_str})
  step_pause
  @row_that_was_swiped = row_id
end

#swipe_to_delete_row(row_id, table_id = nil) ⇒ Object



435
436
437
438
439
440
441
442
443
# File 'lib/briar/table.rb', line 435

def swipe_to_delete_row (row_id, table_id = nil)
  step_pause
  swipe_on_row 'left', row_id, table_id
  step_pause
  should_see_delete_confirmation_in_row row_id, table_id
  touch_delete_confirmation row_id, table_id
  step_pause
  should_not_see_row row_id, table_id
end

#table_exists?(table_name) ⇒ Boolean

Returns:

  • (Boolean)


220
221
222
# File 'lib/briar/table.rb', line 220

def table_exists? (table_name)
  !query("tableView marked:'#{table_name}'", AI).empty?
end

#touch_button_in_row(button_id, row_id, table_id = nil) ⇒ Object



477
478
479
480
481
# File 'lib/briar/table.rb', line 477

def touch_button_in_row(button_id, row_id, table_id=nil)
  query_str = query_str_for_table(table_id)
  touch("#{query_str} descendant button marked:'#{button_id}'")
  step_pause
end

#touch_delete_confirmation(row_id, table_id = nil) ⇒ Object



278
279
280
281
282
# File 'lib/briar/table.rb', line 278

def touch_delete_confirmation(row_id, table_id=nil)
  query_str = query_str_for_confirm_delete_in_row(row_id, table_id)
  touch(query_str)
  step_pause
end

#touch_edit_mode_delete_button(row_id, table_id = nil) ⇒ Object



327
328
329
330
331
332
# File 'lib/briar/table.rb', line 327

def touch_edit_mode_delete_button (row_id, table_id=nil)
  should_see_edit_mode_delete_button row_id, table_id
  touch("tableViewCell marked:'#{row_id}' descendant tableViewCellEditControl marked:'Delete '")
  # this is a wait function - so no step pause is necessary
  should_see_delete_confirmation_in_row row_id
end

#touch_row(row_id, table_id = nil) ⇒ Object



193
194
195
196
197
198
199
200
201
# File 'lib/briar/table.rb', line 193

def touch_row (row_id, table_id = nil)
  should_see_row row_id
  step_pause
  offset = touch_row_offset_hash row_id, table_id
  query_str = query_str_for_row(row_id, table_id)
  #puts "touch(\"#{query_str}\", :offset => #{offset})"
  touch(query_str, :offset => offset)
  step_pause
end

#touch_row_and_wait_to_see(row_id, view, opts = {}) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/briar/table.rb', line 204

def touch_row_and_wait_to_see(row_id, view, opts={})
  if (not opts.is_a?(Hash)) and (not opts.nil?)
    _deprecated('0.1.3',
               "you should no longer pass a table_id '#{opts}' as an arg, pass opts hash instead",
               :warn)
    opts = {:table_id => opts}
  end

  default_opts = {:table_id => nil,
                  :timeout => BRIAR_WAIT_TIMEOUT}
  opts = default_opts.merge(opts)
  should_see_row row_id, opts[:table_id]
  touch_row row_id, opts[:table_id]
  wait_for_view view, opts[:timeout]
end

#touch_row_offset_hash(row_id, table_id = nil) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/briar/table.rb', line 177

def touch_row_offset_hash (row_id, table_id = nil)
  offset = 0
  query = query_str_for_row row_id, table_id
  if tabbar_visible?
    #puts "tabbar visible"
    cells = query(query_str_for_rows, AI)
    #puts "cells = #{cells} is #{row_id} last? ==> #{cells.last.eql?(row_id)}"
    if cells.last.eql?(row_id)
      row_h = query(query, :frame).first['Height'].to_i
      offset = -1 * (row_h/3)
      #puts "offset = #{offset}"
    end
  end
  {:x => 0, :y => offset}
end

#touch_section_header(header_id, table_id = nil) ⇒ Object



471
472
473
474
475
# File 'lib/briar/table.rb', line 471

def touch_section_header (header_id, table_id=nil)
  query_str = query_str_for_table table_id
  touch("#{query_str} descendant view marked:'#{header_id}'")
  step_pause
end

#touch_switch_in_row(switch_id, row_id, opts = {}) ⇒ Object



404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/briar/table.rb', line 404

def touch_switch_in_row (switch_id, row_id, opts={})
  if (not opts.is_a?(Hash)) and (not opts.nil?)
    _deprecated('0.1.1',
               "you should no longer pass a table_id '#{opts}' pass a hash instead",
               :warn)
    opts = {:table_id => opts}
  end

  default_opts = {:table_id => nil,
                  :switch_class => nil}

  opts = default_opts.merge(opts)

  table_id = opts[:table_id]

  switch_class = opts[:switch_class]


  if switch_class.nil?
    switch_query = "switch marked:'#{switch_id}'"
  else
    switch_query = "view:'#{switch_class}' marked:'#{switch_id}'"
  end


  should_see_row row_id, table_id
  query_str = query_str_for_row_content row_id, table_id
  touch("#{query_str} #{switch_query}")
  step_pause
end

#touch_text_field_clear_button_in_row(row_id, table_id = nil) ⇒ Object



371
372
373
374
375
376
377
# File 'lib/briar/table.rb', line 371

def touch_text_field_clear_button_in_row (row_id, table_id=nil)
  query_str = query_str_for_row_content row_id, table_id
  res = query("#{query_str} textField")
  screenshot_and_raise "expected to see text field in '#{row_id}' row" if res.empty?
  touch("#{query_str} textField descendant button")
  step_pause
end

#touch_text_field_in_row_and_wait_for_keyboard(text_field_id, row_id, table_id = nil) ⇒ Object



379
380
381
382
383
384
385
# File 'lib/briar/table.rb', line 379

def touch_text_field_in_row_and_wait_for_keyboard (text_field_id, row_id, table_id=nil)
  should_see_row row_id, table_id
  query_str = query_str_for_row_content row_id, table_id
  touch("#{query_str} textField marked:'#{text_field_id}'")
  step_pause
  should_see_keyboard
end

#wait_for_row(row_id, options = {:table_id => nil, :timeout => BRIAR_WAIT_TIMEOUT}) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/briar/table.rb', line 72

def wait_for_row(row_id, options={:table_id => nil,
                                  :timeout => BRIAR_WAIT_TIMEOUT})
  table_id = options[:table_id]
  query_str = query_str_for_row row_id, table_id
  timeout = options[:timeout] || BRIAR_WAIT_TIMEOUT
  msg = "waited for '#{timeout}' seconds but did not see row '#{query_str}' with query '#{query_str}'"
  wait_for(:timeout => timeout,
           :retry_frequency => BRIAR_WAIT_RETRY_FREQ,
           :post_timeout => BRIAR_WAIT_STEP_PAUSE,
           :timeout_message => msg) do
    row_visible? row_id, table_id
  end
end