Appium.promote_singleton_appium_methods UICatalogpathはここです。
appium_lib/lib/appium_lib/driver.rb
def self.promote_singleton_appium_methods main_module
raise 'Driver is nil' if $driver.nil?
main_module.constants.each do |sub_module|
#noinspection RubyResolve
$driver.public_methods(false).each do |m|
const = main_module.const_get(sub_module)
const.send(:define_singleton_method, m) do |*args, &block|
begin
super(*args, &block) # promote.rb
rescue NoMethodError, ArgumentError
$driver.send m, *args, &block if $driver.respond_to?(m)
end
# override unless there's an existing method with matching arity
end unless const.respond_to?(m) &&
const.method(m).arity == $driver.method(m).arity
end
end
end
何のためのメソッドか?自分で作成したmoduleの中でappiumのメソッドを使えるようにするためです。
サンプルでは自分でmoduleを作成しているのですが、
普通に実装しては、その中でappiumのメソッドは使えません。
module UICatalog
module ButtonUses
class << self
def assert_exists
s_text_exact resolve_id 'ButtonsTitle'
end
def assert
wait { self.assert_exists }
end
end
end
end
Appium.promote_singleton_appium_methods UICatalog←これをコメントすればNoMethodError: undefined method `wait' for UICatalog::Home:Module
というエラーが出ます。
もう少し、詳細にメソッドを見ていきます。
main_module.constantsこれはサンプルでは、下記の内容になります。
UICatalog.constants戻り値です。
[
[0] :ButtonUses,
[1] :ControlUses,
[2] :Home
]
ここでは$driverに含まれているクラスのメソッドが返ります。
$driver.public_methods(false)
main_module.const_get(sub_module)戻り値の一つはこうなります。
UICatalog::ButtonUses上記の値に対してsendで動的にメソッドを定義します。
define_singleton_methodメソッドは、レシーバのオブジェクトに特異メソッドを定義します。
特異メソッドとはインスタンスから呼び出させるメソッドを定義します。
それで、これがどういう意味なるか?
const.send(:define_singleton_method, m)下記のような感じでappiumのメソッドの全てをUICatalog::ButtonUsesに追加していきます。
UICatalog::ButtonUses.define_singleton_method(:wait) UICatalog::ButtonUses.define_singleton_method(:back) UICatalog::ButtonUses.define_singleton_method(:xpath)
0 件のコメント:
コメントを投稿