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