Module: Accessibility::DSL

Defined in:
lib/accessibility/dsl.rb

Overview

DSL methods for AXElements.

The DSL for AXElements is designed to pull actions out from an object and put them in front of object to make communicating test steps seem more like human instructions.

You can read more about the DSL in the Acting section of the AXElements wiki.

Actions collapse

Polling collapse

Mouse Manipulation collapse

Debug Helpers collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args) ⇒ Object

We assume that any method that has the first argument with a type of AX::Element is intended to be an action and so #method_missing will forward the message to the element.

Parameters:

  • meth (String)

    an action constant

Raises:

  • (NoMethodError)


37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/accessibility/dsl.rb', line 37

def method_missing meth, *args
  arg = args.first
  if arg.kind_of? AX::Element
    return arg.perform meth if arg.actions.include? meth
    raise ArgumentError, "`#{meth}' is not an action of #{self}:#{self.class}"
  end
  # @todo do we still need this? we should just call super
  # should be able to just call super, but there is a bug in MacRuby (#1320)
  # so we just recreate what should be happening
  message = "undefined method `#{meth}' for #{self}:#{self.class}"
  raise NoMethodError, message, caller(1)
end

Instance Method Details

#app_with_bundle_identifier(id) ⇒ AX::Application? Also known as: app_with_bundle_id, launch

Find the application with the given bundle identifier. If the application is not already running, it will be launched.

Examples:


app_with_bundle_identifier 'com.apple.finder'
launch                     'com.apple.mail'

Parameters:

  • id (String)

Returns:



890
891
892
# File 'lib/accessibility/dsl.rb', line 890

def app_with_bundle_identifier id
  AX::Application.new id
end

#app_with_name(name) ⇒ AX::Application?

Find the application with the given name. If the application is not already running, it will NOT be launched and this method will return nil.

Examples:


app_with_name 'Finder'

Parameters:

  • name (String)

Returns:



907
908
909
# File 'lib/accessibility/dsl.rb', line 907

def app_with_name name
  AX::Application.new name
end

#app_with_pid(pid) ⇒ AX::Application

Find the application with the given process identifier. An invalid PID will cause an exception to be raised.

Examples:


app_with_pid 35843

Parameters:

  • pid (Fixnum)

Returns:



921
922
923
# File 'lib/accessibility/dsl.rb', line 921

def app_with_pid pid
  AX::Application.new pid
end

#cancel(element) ⇒ Boolean

Try to perform the cancel action on the given element.

Parameters:

Returns:

  • (Boolean)


118
119
120
# File 'lib/accessibility/dsl.rb', line 118

def cancel element
  element.perform :cancel
end

#click(obj = nil, wait = 0.2) { ... } ⇒ Object

Perform a regular click.

If a parameter is provided then the mouse will move to that point first; the argument must respond to #to_point.

If a block is given, it will be yielded to between the click down and click up event.

Examples:


click
click window.close_button
click do
  move_mouse_to [0,0]
end

Parameters:

  • obj (#to_point) (defaults to: nil)

Yields:

  • Optionally take a block that is executed between click down and click up events.



621
622
623
624
625
626
627
628
# File 'lib/accessibility/dsl.rb', line 621

def click obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.click_down
  yield if block_given?
ensure
  Mouse.click_up
  sleep wait
end

#confirm(element) ⇒ Boolean

Try to perform the confirm action on the given element.

Parameters:

Returns:

  • (Boolean)


91
92
93
# File 'lib/accessibility/dsl.rb', line 91

def confirm element
  element.perform :confirm
end

#contextual_menuAX::Menu?

Note:

This is a hack to workaround an AXAPI deficiency

Note:

This method may move or be renamed in the next release, though it will not be removed

Find a contextual menu that is open near the mouses current position

This method assumes that it is being called in the block of a call to #right_click, and that the contextual menu is going to be very close to the mouse pointer.

Returns:



330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/accessibility/dsl.rb', line 330

def contextual_menu
  # CAST, just like high school trigonometry! :P
  c, a, s, t = quads = Array.new(4) { Mouse.current_position }
  c.x -= 10; c.y += 10
  a.x += 10; a.y += 10
  s.x += 10; s.y -= 10
  t.x -= 10; t.y -= 10
  elements = quads.map { |quad| element_at_point quad }
  elements.uniq!
  elements.map! { |el| el.kind_of?(AX::Menu) ? el : el.ancestor(:menu) }
  elements.find { |element| element.present? }
end

#decrement(element) ⇒ Boolean

Try to perform the decrement action on the given element.

Parameters:

Returns:

  • (Boolean)


82
83
84
# File 'lib/accessibility/dsl.rb', line 82

def decrement element
  element.perform :decrement
end

#delete(element) ⇒ Boolean

Try to perform the delete action on the given element.

Parameters:

Returns:

  • (Boolean)


109
110
111
# File 'lib/accessibility/dsl.rb', line 109

def delete element
  element.perform :delete
end

#double_click(obj = nil, wait = 0.2) ⇒ Object

Perform a double click action.

If an argument is provided then the mouse will move to that point first; the argument must respond to #to_point.

Parameters:

  • obj (#to_point) (defaults to: nil)


660
661
662
663
664
# File 'lib/accessibility/dsl.rb', line 660

def double_click obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.double_click
  sleep wait
end

#drag_mouse_to(arg, opts = {}) ⇒ Object

Click and drag the mouse from its current position to the given position.

There are many reasons why you would want to cause a drag event with the mouse. Perhaps you want to drag an object to another place, or maybe you want to select a group of objects on the screen.

Examples:


drag_mouse_to [100,100]
drag_mouse_to drop_zone, from: desktop_icon

Parameters:

  • arg (#to_point)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :from (#to_point)

    a point to move to before dragging

  • :duration (Number) — default: 0.2

    in seconds

  • :wait (Number) — default: 0.2

    in seconds



555
556
557
558
559
# File 'lib/accessibility/dsl.rb', line 555

def drag_mouse_to arg, opts = {}
  move_mouse_to opts[:from] if opts[:from]
  Mouse.drag_to arg.to_point, (opts[:duration] || 0.2)
  sleep(opts[:wait] || 0.2)
end

#element_at_point(point, opts = {}) ⇒ AX::Element Also known as: element_at

Get the top most object at an arbitrary point on the screen for the given application. The given point can be a CGPoint, an Array, or anything else that responds to #to_point.

Optionally, you can look for the top-most element for a specific application by passing an AX::Application object using the for: key.

Examples:


element_at [100, 456]
element_at CGPoint.new(33, 45), for: safari

element_at window # find out what is in the middle of the window

Parameters:

  • point (#to_point)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

Returns:



963
964
965
966
# File 'lib/accessibility/dsl.rb', line 963

def element_at_point point, opts = {}
  base = opts[:for] || system_wide
  base.element_at point
end

#element_under_mouseAX::Element

Return the top most element at the current mouse position.

See #element_at_point for more details.

Returns:



939
940
941
# File 'lib/accessibility/dsl.rb', line 939

def element_under_mouse
  element_at_point Mouse.current_position
end

#graph(element) ⇒ String Also known as: graph_for

Note:

This method is currently experimental

Note:

You will need to have GraphViz command line tools installed in order for this to work.

Make and open a dot format graph of the tree, meant for graphing with GraphViz.

Examples:


graph app.main_window

Parameters:

Returns:

  • (String)

    path to the saved image



817
818
819
820
821
822
823
# File 'lib/accessibility/dsl.rb', line 817

def graph element
  require 'accessibility/graph'
  graph = Accessibility::Graph.new(element)
  path  = graph.generate_png!
  `open #{path}`
  path
end

#hide(app) ⇒ Boolean

Tell an app to hide itself.

Parameters:

Returns:

  • (Boolean)


144
145
146
# File 'lib/accessibility/dsl.rb', line 144

def hide app
  app.perform :hide
end

#highlight(obj, opts = {}) ⇒ Accessibility::Highlighter

Highlight an element on screen. You can optionally specify the highlight colour or pass a timeout to automatically have the highlighter disappear.

The highlighter is actually a window, so if you do not set a timeout, you will need to call #stop or #close on the returned highlighter object in order to get rid of the highlighter.

You could use this method to highlight an arbitrary number of elements on screen, with a rainbow of colours. Great for debugging.

Examples:


highlighter = highlight window.outline
# wait a few seconds...
highlighter.stop

# highlighter automatically turns off after 5 seconds
highlight window.outline.row, colour: NSColor.greenColor, timeout: 5

Parameters:

  • obj (#to_rect)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :timeout (Number)
  • :colour (NSColor) — default: NSColor.magentaColor

Returns:

  • (Accessibility::Highlighter)


799
800
801
# File 'lib/accessibility/dsl.rb', line 799

def highlight obj, opts = {}
  Accessibility::Highlighter.new obj, opts
end

#horizontal_scroll(lines, obj = nil, wait = 0.1) ⇒ Object

TODO:

Need to expose the units option? Would allow scrolling by pixel.

Horizontally scrolls an arbitrary number of lines at the mouses current point on the screen

Use a positive number to scroll left, and a negative number to scroll right.

If the second argument is provided then the mouse will move to that point first; the argument must respond to #to_point.

Parameters:

  • lines (Number)
  • obj (#to_point) (defaults to: nil)
  • wait (Number) (defaults to: 0.1)


595
596
597
598
599
# File 'lib/accessibility/dsl.rb', line 595

def horizontal_scroll lines, obj = nil, wait = 0.1
  move_mouse_to obj, wait: 0 if obj
  Mouse.horizontal_scroll lines
  sleep wait
end

#increment(element) ⇒ Boolean

Try to perform the increment action on the given element.

Parameters:

Returns:

  • (Boolean)


100
101
102
# File 'lib/accessibility/dsl.rb', line 100

def increment element
  element.perform :increment
end

#move_mouse_to(arg, opts = {}) ⇒ Object

Move the mouse cursor to the given point or object on the screen.

Examples:


move_mouse_to button
move_mouse_to [344, 516]
move_mouse_to CGPoint.new(100, 100)

Parameters:

  • arg (#to_point)
  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :duration (Number) — default: 0.2

    in seconds

  • :wait (Number) — default: 0.2

    in seconds



528
529
530
531
532
533
534
535
# File 'lib/accessibility/dsl.rb', line 528

def move_mouse_to arg, opts = {}
  duration = opts[:duration] || 0.2
  if Accessibility.debug? && arg.kind_of?(AX::Element)
    highlight arg, timeout: duration, color: NSColor.orangeColor
  end
  Mouse.move_to arg.to_point, duration
  sleep(opts[:wait] || 0.2)
end

#pick(element) ⇒ Boolean

Try to perform the pick action on the given element.

Parameters:

Returns:

  • (Boolean)


73
74
75
# File 'lib/accessibility/dsl.rb', line 73

def pick element
  element.perform :pick
end

#pinch(direction, magnification = 1, obj = nil, wait = 0.2) ⇒ Object

Perform a pinch gesture in the given direction

You can optionally specify the magnification factor and position for the pinch event. * Available pinch directions are:

  • :zoom or :expand
  • :unzoom or :contract

Magnification is a relative magnification setting. A zoom value of 1.0 means 1.0 more than the current zoom level. 2.0 would be 2.0 levels higher than the current zoom.

You can also optionally specify an object/point on screen for the mouse pointer to be moved to before the gesture begins.

Parameters:

  • direction (Symbol)
  • magnification (Float) (defaults to: 1)
  • obj (#to_point) (defaults to: nil)


725
726
727
728
729
# File 'lib/accessibility/dsl.rb', line 725

def pinch direction, magnification = 1, obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.pinch direction, magnification
  sleep wait
end

#press(element) ⇒ Boolean

Try to perform the press action on the given element.

Parameters:

Returns:

  • (Boolean)


55
56
57
# File 'lib/accessibility/dsl.rb', line 55

def press element
  element.perform :press
end

#raise(element) ⇒ Boolean #raise(exception[, message[, backtrace]]) ⇒ Object

Note:

This method overrides Kernel#raise so we have to check the class of the first argument to decide which code path to take.

Try to perform the raise action on the given element.

Overloads:

  • #raise(element) ⇒ Boolean

    Parameters:

    Returns:

    • (Boolean)
  • #raise(exception[, message[, backtrace]]) ⇒ Object

    The normal way to raise an exception.



134
135
136
137
# File 'lib/accessibility/dsl.rb', line 134

def raise *args
  arg = args.first
  arg.kind_of?(AX::Element) ? arg.perform(:raise) : Kernel.raise(*args)
end

#record(file = nil) {|recorder| ... } ⇒ String

See (ScreenRecorder)[http://rdoc.info/gems/screen_recorder/frames] for details on the screen recording options

Examples:


file = record do
  run_tests
end
`open '#{file}'`

Parameters:

  • file (String) (defaults to: nil)

Yields:

Yield Parameters:

  • recorder (ScreenRecorder)

Returns:

  • (String)


867
868
869
870
871
872
873
874
# File 'lib/accessibility/dsl.rb', line 867

def record file = nil, &block
  require 'screen_recorder'
  if file
    ScreenRecorder.record file, &block
  else
    ScreenRecorder.record &block
  end
end

#right_click(obj = nil, wait = 0.2) { ... } ⇒ Object Also known as: secondary_click

Perform a right (a.k.a. secondary) click action.

If an argument is provided then the mouse will move to that point first; the argument must respond to #to_point.

If a block is given, it will be yielded to between the click down and click up event. This behaviour is the same as passing a block to #click.

Parameters:

  • obj (#to_point) (defaults to: nil)

Yields:

  • Optionally take a block that is executed between click down and click up events.



643
644
645
646
647
648
649
650
# File 'lib/accessibility/dsl.rb', line 643

def right_click obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.right_click_down
  yield if block_given?
ensure
  Mouse.right_click_up
  sleep wait
end

#rotate(direction, angle, obj = nil, wait = 0.2) ⇒ Object

Perform a rotation gesture in the given direction the given angle degrees

Possible directions are:

  • :cw, ':clockwise, ':clock_wise to rotate in the clockwise direction
  • :ccw, ':counter_clockwise,:counter_clock_wise` to rotate in the the counter clockwise direction

The angle parameter is a number of degrees to rotate. There are 360 degrees in a full rotation, as you would expect in Euclidian geometry.

You can also optionally specify an object/point on screen for the mouse pointer to be moved to before the gesture begins. The movement will be instantaneous.

Parameters:

  • direction (Symbol)
  • angle (Float)
  • obj (#to_point) (defaults to: nil)


751
752
753
754
755
# File 'lib/accessibility/dsl.rb', line 751

def rotate direction, angle, obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.rotate direction, angle
  sleep wait
end

#screenshot(rect = CGRect.new(CGPoint.new(0, 0), CGSize.new(-1, -1)), path = '~/Desktop') ⇒ String Also known as: capture_screen

Take a screen shot and save it to disk. If a file path is not given then the default value will put it on the desktop. The actual file name will automatically generated with a timestamp.

Examples:


screenshot
  # => "~/Desktop/AXElements-ScreenShot-20120422184650.png"

screenshot app.main_window
  # => "~/Desktop/Safari-20120422184650.png"

screenshot app.main_window, "/Volumes/SecretStash"
  # => "/Volumes/SecretStash/AXElements-ScreenShot-20150622032250.png"

Parameters:

  • rect (#to_rect) (defaults to: CGRect.new(CGPoint.new(0, 0), CGSize.new(-1, -1)))
  • path (#to_s) (defaults to: '~/Desktop')

Returns:

  • (String)

    path to the screenshot



845
846
847
848
849
# File 'lib/accessibility/dsl.rb', line 845

def screenshot rect = CGRect.new(CGPoint.new(0, 0), CGSize.new(-1, -1)),
               path = '~/Desktop'
  require 'accessibility/screen_shooter'
  ScreenShooter.shoot rect.to_rect, path
end

#scroll(lines, obj = nil, wait = 0.1) ⇒ Object

TODO:

Need to expose the units option? Would allow scrolling by pixel.

Scrolls an arbitrary number of lines at the mouses current point on the screen. Use a positive number to scroll down, and a negative number to scroll up.

If the second argument is provided then the mouse will move to that point first; the argument must respond to #to_point.

Parameters:

  • lines (Number)
  • obj (#to_point) (defaults to: nil)
  • wait (Number) (defaults to: 0.1)


574
575
576
577
578
# File 'lib/accessibility/dsl.rb', line 574

def scroll lines, obj = nil, wait = 0.1
  move_mouse_to obj, wait: 0 if obj
  Mouse.scroll lines
  sleep wait
end

#scroll_menu_to(element)

This method returns an undefined value.

Scroll a menu to an item in the menu and then move the mouse pointer to that item.

Examples:


click window.pop_up do
  scroll_menu_to pop_up.menu.item(title: "Expensive Cake")
end

Parameters:



314
315
316
# File 'lib/accessibility/dsl.rb', line 314

def scroll_menu_to element
  element.ancestor(:menu).scroll_to element
end

#scroll_to(element) Also known as: scroll_to_visible

This method returns an undefined value.

Scroll through a scroll area until the given element is visible.

If you need to scroll an unknown amount of units through a table or another type of object contained in as scroll area, you can just pass the element that you are trying to get to and this method will scroll to it for you.

Examples:


scroll_to table.rows.last

Parameters:



297
298
299
# File 'lib/accessibility/dsl.rb', line 297

def scroll_to element
  element.ancestor(:scroll_area).scroll_to element
end

#select_menu_item(app, *path) ⇒ Boolean

Navigate the menu bar menus for the given application and select the last item in the chain.

Examples:


mail = app_with_name 'Mail'
select_menu_item mail, 'View', 'Sort By', 'Subject'
select_menu_item mail, 'Edit', /Spelling/, /show spelling/i

Parameters:

Returns:

  • (Boolean)


256
257
258
# File 'lib/accessibility/dsl.rb', line 256

def select_menu_item app, *path
  app.application.select_menu_item *path
end

#set(element, attribute_name: new_value) ⇒ Object #set(element, new_value) ⇒ Object

Set the value of an attribute on an element.

This method will try to set focus to the element first; this is to compensate for cases where app developers assumed an element would have to have focus before a user could change the value.

Examples:


set text_field, selected_text_range: 1..10

set text_field,   'Mark Rada'
set radio_button, 1

Overloads:

  • #set(element, attribute_name: new_value) ⇒ Object

    Set a specified attribute to a new value

    Parameters:

  • #set(element, new_value) ⇒ Object

    Set the value attribute to a new value

    Parameters:



207
208
209
210
211
212
213
214
215
# File 'lib/accessibility/dsl.rb', line 207

def set element, change
  set_focus_to element

  if change.kind_of? Hash
    element.set *change.first
  else
    element.set :value, change
  end
end

#set_focus_to(element) ⇒ Object Also known as: set_focus

TODO:

Introduce a method to set focus to closest ancestor that supports focus.

Focus an element on the screen, but only if it can be directly focused. It is safe to pass any element into this method as nothing will happen if it does not have a writable focused state attribute.

Parameters:



176
177
178
# File 'lib/accessibility/dsl.rb', line 176

def set_focus_to element
  element.set(:focused, true) if element.writable? :focused
end

#show_about_window_for(app) ⇒ AX::Window

Show the "About" window for an app. Returns the window that is opened.

Parameters:

Returns:

  • (AX::Window)


266
267
268
# File 'lib/accessibility/dsl.rb', line 266

def show_about_window_for app
  app.show_about_window
end

#show_menu(element) ⇒ Boolean

Try to perform the show_menu action on the given element.

Parameters:

Returns:

  • (Boolean)


64
65
66
# File 'lib/accessibility/dsl.rb', line 64

def show_menu element
  element.perform :show_menu
end

#show_preferences_window_for(app) ⇒ AX::Window

Note:

This method assumes that the app has setup the standard CMD+, hotkey to open the pref window

Try to open the preferences for an app. Returns the window that is opened.

Parameters:

Returns:

  • (AX::Window)


279
280
281
# File 'lib/accessibility/dsl.rb', line 279

def show_preferences_window_for app
  app.application.show_preferences_window
end

#smart_magnify(obj = nil, wait = 0.2) ⇒ Object

Perform a smart magnify (double tap on trackpad)

You can optionally specify an object/point on the screen where to perform the smart magnification. The mouse will move to this point first

Parameters:

  • obj (#to_point) (defaults to: nil)


764
765
766
767
768
# File 'lib/accessibility/dsl.rb', line 764

def smart_magnify obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.smart_magnify
  sleep wait
end

#swipe(direction, obj = nil, wait = 0.2) ⇒ Object

Perform a swipe gesture in the given direction

Valid directions are:

  • :up
  • :down
  • :left
  • :right

An optional second argument can be provided. If the argument is provided then the mouse pointer will move to that point first.

Examples:


swipe :left, safari.web_area

Parameters:

  • direction (Symbol)
  • obj (#to_point) (defaults to: nil)


698
699
700
701
702
# File 'lib/accessibility/dsl.rb', line 698

def swipe direction, obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.swipe direction
  sleep wait
end

#system_wideAX::SystemWide

Synonym for AX::SystemWide.new.

Returns:



929
930
931
# File 'lib/accessibility/dsl.rb', line 929

def system_wide
  AX::SystemWide.new
end

#terminate(app) ⇒ Boolean

Tell an app to quit.

Parameters:

Returns:

  • (Boolean)


163
164
165
# File 'lib/accessibility/dsl.rb', line 163

def terminate app
  app.perform :terminate
end

#triple_click(obj = nil, wait = 0.2) ⇒ Object

Perform a triple click action

If an argument is provided then the mouse will move to that point first; the argument must respond to #to_point.

Parameters:

  • obj (#to_point) (defaults to: nil)


673
674
675
676
677
# File 'lib/accessibility/dsl.rb', line 673

def triple_click obj = nil, wait = 0.2
  move_mouse_to obj, wait: 0 if obj
  Mouse.triple_click
  sleep wait
end

#type(string) ⇒ Object #type(string, app) ⇒ Object Also known as: type_string

Simulate keyboard input by typing out the given string. To learn more about how to encode modifier keys (e.g. Command), see the dedicated documentation page on Keyboard Events wiki page.

Examples:


type "Hello, world!"

Overloads:

  • #type(string) ⇒ Object

    Send input to the currently focused application

    Parameters:

    • string (String)
  • #type(string, app) ⇒ Object

    Send input to a specific application

    Parameters:



237
238
239
240
# File 'lib/accessibility/dsl.rb', line 237

def type string, app = system_wide
  sleep 0.1
  app.type string.to_s
end

#unhide(app) ⇒ Boolean Also known as: show

Tell an app to unhide itself.

Parameters:

Returns:

  • (Boolean)


153
154
155
# File 'lib/accessibility/dsl.rb', line 153

def unhide app
  app.perform :unhide
end

#wait_for(element, filters = {}) { ... } ⇒ AX::Element?

Simply wait around for something to show up. This method is similar to performing an explicit search on an element except that the search filters take two extra options which can control the timeout period and the search subtree. You MUST supply either the parent or ancestor option to specify where to search from. Searching from the parent implies that what you are waiting for is a child of the parent and not a more distant descendant.

This is an alternative to using the notifications system. It is far easier to use than notifications in most cases, but it will perform more slowly (and without all the fun crashes).

Examples:


# Waiting for a dialog window to show up
wait_for :dialog, parent: app

# Waiting for a hypothetical email from Mark Rada to appear
wait_for :static_text, value: 'Mark Rada', ancestor: mail.main_window

# Waiting for something that will never show up
wait_for :a_million_dollars, ancestor: fruit_basket, timeout: 1000000

Parameters:

  • element (#to_s)
  • filters (Hash) (defaults to: {})

Options Hash (filters):

Yields:

  • Optional block used as a search filter

Returns:



377
378
379
380
381
382
383
384
385
# File 'lib/accessibility/dsl.rb', line 377

def wait_for element, filters = {}, &block
  if filters.has_key? :ancestor
    wait_for_descendant element, filters.delete(:ancestor), filters, &block
  elsif filters.has_key? :parent
    wait_for_child element, filters.delete(:parent), filters, &block
  else
    raise ArgumentError, 'parent/ancestor filter required'
  end
end

#wait_for_child(child, parent, filters, &block) ⇒ AX::Element?

Note:

This is really just an optimized case of #wait_for_descendant when you know what you are waiting for is a child of a particular element. Use #wait_for_descendant if you are unsure of the relationship.

Wait around for particular element and then return that element. The parent argument must be the parent of the element you are waiting for, this method will not look further down the hierarchy. The options you pass to this method can be any search filter that you can normally use.

See #wait_for for more details.

Parameters:

Returns:



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/accessibility/dsl.rb', line 438

def wait_for_child child, parent, filters, &block
  timeout = filters.delete(:timeout) || 5
  start   = Time.now
  q       = Accessibility::Qualifier.new(child, filters, &block)
  until Time.now - start > timeout
    result = nil

    begin
      result = parent.children.find { |x| q.qualifies? x }
    rescue RuntimeError => e
      # This is a temporary workaround; accessibility_core should
      # raise a specific error class for this issue or not use
      # exceptions for this problem at all...
      raise e unless e.message.match(/application is busy/)
    end

    return result unless result.blank?
    sleep 0.1
  end
  nil
end

#wait_for_descendant(descendant, ancestor, filters, &block) ⇒ AX::Element? Also known as: wait_for_descendent

Wait around for particular element and then return that element. The options you pass to this method can be any search filter that you can normally use.

See #wait_for for more details.

Parameters:

Returns:



398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/accessibility/dsl.rb', line 398

def wait_for_descendant descendant, ancestor, filters, &block
  timeout = filters.delete(:timeout) || 5
  start   = Time.now
  until Time.now - start > timeout
    result = nil

    begin
      result = ancestor.search(descendant, filters, &block)
    rescue RuntimeError => e
      # This is a temporary workaround; accessibility_core should
      # raise a specific error class for this issue or not use
      # exceptions for this problem at all...
      raise e unless e.message.match(/application is busy/)
    end

    return result unless result.blank?
    sleep 0.1
  end
  nil
end

#wait_for_invalidation_of(element) ⇒ Boolean #wait_for_invalidation_of(kind, filters = {}, &block) ⇒ Boolean Also known as: wait_for_invalidation, wait_for_invalid

Simply wait for an element to disappear. Optionally wait for the element to appear first.

Like #wait_for, you can pass any search filters that you normally would, including blocks. However, this method also supports the ability to pass an AX::Element and simply wait for it to become invalid.

An example usage would be typing into a search field and then waiting for the busy indicator to disappear and indicate that all search results have been returned.

Overloads:

  • #wait_for_invalidation_of(element) ⇒ Boolean

    Examples:

    
    wait_for_invalidation_of table.row(static_text: { value: 'Cake' })

    Parameters:

    Returns:

    • (Boolean)
  • #wait_for_invalidation_of(kind, filters = {}, &block) ⇒ Boolean

    Examples:

    
    wait_for_invalidation_of :row, parent: table, static_text: { value: 'Cake' }

    Parameters:

    • element (#to_s)
    • filters (Hash) (defaults to: {})

    Options Hash (filters):

    • :timeout (Number) — default: 5

      in seconds

    Returns:

    • (Boolean)


493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'lib/accessibility/dsl.rb', line 493

def wait_for_invalidation_of element, filters = {}, &block
  timeout = filters[:timeout] || 5
  start   = Time.now

  unless element.kind_of? AX::Element
    element = wait_for element, filters, &block
    # this is a tricky situation,
    return true unless element
  end

  until Time.now - start > timeout
    return true if element.invalid?
    sleep 0.1
  end
  false
end