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 endAppium.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 件のコメント:
コメントを投稿