Feature #10767

Robust class hierarchy for applications in the test suite

Added by anonym 2015-12-16 16:01:41 . Updated 2015-12-16 18:49:15 .

Status:
Confirmed
Priority:
Normal
Assignee:
anonym
Category:
Test suite
Target version:
Start date:
2015-12-16
Due date:
% Done:

0%

Feature Branch:
Type of work:
Code
Blueprint:

Starter:
Affected tool:
Deliverable for:

Description

Here’s a quick brain dump of something I’ve been thinking about lately:

Currently we employ various “helper” functions for doing stuff in a robust manner for certain applications in the automated test suite. Sometimes these could benefit other applications too, or be generalized so they can. Imagine a class hierarchy like this, where the most robust of our tricks would be inherited downwards (and when they don’t work, overridden):

  • App
    • CLIApp (which perhaps starts stuff with VM.spawn()? I’m not sure if there’s much use for this, so XorgApp would become the new root, but called just App.)
    • XorgApp
      • QtApp
        • ElectrumApp
        • VidaliaApp
      • GtkApp
        • BrowserApp
          • TorBrowserApp
          • I2PBrowserApp
          • UnsafeBrowserApp
        • IcedoveApp
        • PidginApp
        • GnomeApp
          • GeditApp
          • GnomeTermialApp
          • FilesApp

Hopefully Gedit could be implemented as simply as this:

class GeditApp < GnomeApp
  # Possibly we could have a @name that would derive the below ones, that would work in most cases
  @app_menu_icon = 'GnomeApplicationGedit.png'
  @exec_path = '/usr/bin/gedit'
  # Another interesting idea would be to parse .desktop files, perhaps.
end


and then we could do stuff like:

gedit = GeditApp.new
# Since @app_menu_icon is set, it will start via the menu.
gedit.start
puts "#{gedit.name} (#{gedit.exec_path}) started with pid #{gedit.pid}"
gedit.focus
# Call Sikuli's type(), which probably should be auto-focusing (which makes
# the focus above unnecessary, but let's keep it for the demonstration)
gedit.type("typing some text " + Sikuli::Key.ENTER)
1000.times { gedit.type(Sikuli::Key.ENTER) }
# Will error out if there's no GNOME style scrollbar. Or just succeed since we
# could consider this as being at the top?
gedit.scroll_to_top
# This will click the X-button of Gedit's window.
gedit.close
# This may not work so well with GNOME applications since they seem to
# gravitate to ad-hoc, non-standardized menus, but you get the idea. Either
# we can use assistive tech to navigate, or we derive the images for sikuli to
# click on, e.g. "File" => "GnomeAppMenuFile.png".
gedit.open_menu(["File", "Save As"])
# children() fetches the list of child windows/prompts etc, and now we expect
# only one, the "Save changes before closing?" prompt. 
gedit.children.first.click('GeditCloseWithoutSaving.png')
# I guess we could make children() implement Enumerable and have find() look for
# the window title so we could have done the above like this:
#   gedit.children.find('Save As').click('GeditCloseWithoutSaving.png')

Focusing and so on would be automatic on “actions”, so we could run several instances of the same application in a robust way, without mixing up where stuff happens.

I guess one-off application instances could be started like this:

  gedit_instance = GnomeApp.new(:exec_path => '/usr/bin/gedit', ...)
  gedit_instance.start


or, simplified,

  gedit_instance = GnomeApp.start(:exec_path => '/usr/bin/gedit', ...)


so in many cases we wouldn’t need to define a dedicated class.

Ideally Feature #10721 would also play a big role in this somehow so we can depend less on Sikuli and images.


Subtasks


History

#1 Updated by anonym 2015-12-16 16:20:43

  • Description updated

#2 Updated by anonym 2015-12-16 18:49:15

  • Description updated