# Used for modeling the current screen by Rtml::Test::TmlApplication. class Rtml::Test::Screen delegate :[], :[]=, :/, :to_s, :to => :screen def initialize(tml) @screen = tml end def ==(screen) id == screen.id end def id @screen['id'] end def display? !((@screen / "display") || []).empty? end def variant_with_hotkey(which) possible_variants.each { |variant| return variant[:uri] if variant[:key] == which } nil end def card_readers ((@screen / "card") || []) end def uri_for_hotkey(which) if variant = variant_with_hotkey(which) return variant end return @screen[which] if @screen[which] nil end # Returns the +next+ element for this screen, or nil if there is none. def next_element ((@screen / "next") || []).shift end # Returns the hyperlink Hpricot element, if there's only one; nil if there are none; and raises an # Rtml::Errors::ApplicationError if there are multiple links (because there's no inference as to which link to # follow). def autoselect_hyperlink if !(links = hyperlinks).empty? if links.length > 1 raise Rtml::Errors::ApplicationError, "Cannot auto-select hyperlink: too many choices on screen #{id.inspect}" end links.shift else nil end end def hyperlinks (@screen / "a") || [] end # Returns true if this screen is an input screen (that is, if it will halt program flow # waiting for user input). def input? return true if !choices.empty? Rtml::Test::TmlApplication::USER_INPUT_ELEMENTS.each { |ele| return true if !(@screen / ele).empty? } false end def timeout return @screen['timeout'].to_i if @screen['timeout'] nxt = ((@screen / "next") || []).shift if nxt return nxt['timeout'].to_i if nxt['timeout'] ((nxt / "variant") || []).each do |var| return var['timeout'].to_i if var['timeout'] end end 0 end def setvars ((@screen / "setvar") || []) end # Returns an array of URIs that can be chosen by the user at this time, or an empty # array if none can be chosen. This inversely coincides with #next_screen in that choices # are only available if #next_screen returns an empty array, just as #next_screen will only # return an empty array if choices are available. def choices choices = (@screen / "a").collect do |a| a['href'] end ((@screen / "variant") || []).each do |variant| choices << variant['uri'] if variant['key'] end choices end # Returns an array of Hashes representing all possible non-user interaction-requiring variants # from this screen. These are returned regardless of whether user interation is required at this time. # # The hashes are laid out thusly: # { :uri => "destination_uri", :key => "hotkey", :timeout => "seconds", :lo => "left_operand", # :op => "operation", :ro => "right_operand" } # # Note that some of these keys may be omitted, according to the TML rules for the +variant+ element. # # For TML +next+ elements, all keys except :uri are omitted. # def possible_variants variants = ((@screen / "variant") || []).collect do |variant| { :uri => variant['uri'], :key => variant['key'], :timeout => variant['timeout'], :lo => variant['lo'], :op => variant['op'], :ro => variant['ro'] }.optionalize end if !(nxt = (@screen / "next") || []).empty? variants << { :uri => nxt.first['uri'] } else variants << { :uri => @screen['next'] } end variants end private attr_reader :screen end