lib/calabash.rb in calabash-1.9.9.pre3 vs lib/calabash.rb in calabash-2.0.0.pre1

- old
+ new

@@ -43,26 +43,62 @@ include Calabash::Interactions extend Calabash::Defaults require 'calabash/page' - # Instantiate a page object. + # Instantiate a page object for the current platform. # + # @note Your pages **must** be in the scope of either Android or IOS. See the + # examples for details. + # # @example - # # android/pages/login_page.rb - # class Android::LoginPage < Calabash::Page + # # android/pages/my_page.rb + # class Android::MyPage < Calabash::Page # include Calabash::Android # - # [...] + # # [...] # end # # # step definition - # Given([...]) do + # Given(/[...]/) do # # Calabash will determine your platform and pick the Android page. - # page(LoginPage).method + # page(MyPage).method # end # + # @example + # # This example shows page code sharing across iOS and Android + # # Please see the sample 'shared-page-logic' for details. + # # pages/abstract_login_page.rb + # class AbstractLoginPage < Calabash::Page + # def login(username, password) + # enter_text_in(username_field, username) + # # [...] + # end + # + # private + # + # def username_field + # abstract_method! + # end + # end + # + # # pages/android_login_page.rb + # class Android::LoginPage < SharedLoginPage + # include Calabash::Android + # + # private + # + # def username_field + # "* marked:'a_username'" + # end + # + # # [...] + # end + # + # + # @see #android? + # @see #ios? # @param [Class] page_class The page to instantiate # @return [Calabash::Page] An instance of the page class def page(page_class) if android? platform_module = Object.const_get(:Android) @@ -74,13 +110,15 @@ unless page_class.is_a?(Class) raise ArgumentError, "Expected a 'Class', got '#{page_class.class}'" end - page_name = page_class.name.split('::').last - if platform_module.const_defined?(page_name, false) + page_name = page_class.name + full_page_name = "#{platform_module}::#{page_name}" + + if Calabash.is_defined?(full_page_name) page_class = platform_module.const_get(page_name, false) if page_class.is_a?(Class) page = page_class.send(:new, self) @@ -91,22 +129,30 @@ end else raise "Page '#{page_class}' is not a class" end else - raise "No such page defined '#{platform_module}::#{page_name}'" + raise "No such page defined '#{full_page_name}'" end end - # Is the app under test running on Android? + # Is the device under test running Android? + # + # @return [Boolean] Returns true if + # {Calabash::Defaults#default_device Calabash.default_device} is an instance + # of {Calabash::Android::Device}. def android? - Android.const_defined?(:Device) && Device.default.is_a?(Android::Device) + Android.const_defined?(:Device, false) && Device.default.is_a?(Android::Device) end - # Is the app under test running on iOS? + # Is the device under test running iOS? + # + # @return [Boolean] Returns true if + # {Calabash::Defaults#default_device Calabash.default_device} is an instance + # of {Calabash::IOS::Device}. def ios? - IOS.const_defined?(:Device) && Device.default.is_a?(IOS::Device) + IOS.const_defined?(:Device, false) && Device.default.is_a?(IOS::Device) end # @!visibility private def self.new_embed_method!(method) EmbeddingContext.new_embed_method(method) @@ -158,10 +204,33 @@ new_embed_method!(cucumber_embed) end end # @!visibility private + def self.is_defined?(string, scope = Object) + constant, rest = string.split('::', 2) + + begin + scope.const_defined?(constant.to_sym, false) && + (!rest || is_defined?(rest, scope.const_get(constant, false))) + rescue NameError => _ + false + end + end + + # @!visibility private + def self.recursive_const_get(string, scope = Object) + constant, rest = string.split('::', 2) + + if rest + recursive_const_get(rest, scope.const_get(constant.to_sym, false)) + else + scope.const_get(constant.to_sym, false) + end + end + + # @!visibility private def self.on_cucumber_context(base) on_new_context(base) end # @!visibility private @@ -190,6 +259,48 @@ Object.const_set(:Android, Module.new) end unless Object.const_defined?(:IOS) Object.const_set(:IOS, Module.new) +end + +if Calabash::Environment::DEBUG_CALLED_METHODS + $stdout.puts "#{Calabash::Color.red("Will print every Calabash method called!")}" + $stdout.puts "#{Calabash::Color.red("Warning: This might slow down your test drastically")}" + $stdout.puts "#{Calabash::Color.red("and is an experimental feature.")}" + + calabash_file = Calabash.method(:extended).source_location.first + $__calabash_dir_name = File.dirname(calabash_file) + + trace_func = lambda do |event, file, line, id, binding, classname| + if event == 'call' + if classname.to_s.split('::').first == 'Calabash' + binding_caller_locations = binding.eval("caller_locations") + files = binding_caller_locations[3..-1].map(&:path) + + calabash_not_in_stacktrace = files.none? do |file| + file.start_with?($__calabash_dir_name) && + File.basename(file) != 'page.rb' + end + + if calabash_not_in_stacktrace + unless id == :included || id == :extended || id == :inherited + arguments = {} + + binding.eval('local_variables').each do |variable| + arguments[variable] = binding.eval(variable.to_s) + end + + # The arguments will be in order + if arguments.empty? + $stdout.puts "Calabash method called: #{id}" + else + $stdout.puts "Calabash method called: #{id}(#{arguments.values.map(&:inspect).join(', ')})" + end + end + end + end + end + end + + set_trace_func(trace_func) end