@@ -135,25 +135,21 @@ def update_sending_request_to(protocol:, host:, port:, path:)
135135 # drivers/plugins in Appium 2.0. Appium 2.0 and its custom drivers/plugins allow you
136136 # to define custom commands that are not part of W3C spec.
137137 #
138+ # Uses Selenium's +Bridge.add_command+ under the hood to register the command
139+ # and define the method on the bridge.
140+ #
138141 # @param [Symbol] method HTTP request method as https://www.w3.org/TR/webdriver/#endpoints
139142 # @param [string] url The url to URL template as https://www.w3.org/TR/webdriver/#endpoints.
140143 # +:session_id+ is the placeholder of 'session id'.
141144 # Other place holders can be specified with +:+ prefix like +:id+.
142145 # Then, the +:id+ will be replaced with a given value as the seconds argument of +execute+
143146 # @param [Symbol] name The name of method that is called as the driver instance method.
144- # @param [Proc] block The block to involve as the method.
145- # Please define a method that has the same +name+ with arguments you want.
146- # The method must has +execute+ method. tHe +execute+ is calls the +url+
147- # with the given parameters.
148- # The first argument should be +name+ as symbol.
149- # The second argument should be hash. If keys in the hash matches +:+ prefix
150- # string in the given url, the matched string in the given url will be
151- # values in the hash.
152- # The third argument should be hash. The hash will be the request body.
153- # Please read examples below for more details.
147+ # @param [Proc] block The block becomes the method body. It is executed in the context of
148+ # the bridge instance, so +execute+ is available. When no block is given,
149+ # a default implementation calling +execute(name)+ is used.
154150 # @raise [ArgumentError] If the given +method+ is invalid value.
155151 #
156- # @example
152+ # @example Simple GET command (no block)
157153 #
158154 # @driver.add_command(
159155 # method: :get,
@@ -163,30 +159,37 @@ def update_sending_request_to(protocol:, host:, port:, path:)
163159 # # Send a GET request to 'session/<session id>/path/to/custom/url'
164160 # @driver.test_command
165161 #
162+ # @example POST command with arguments (do/end block)
166163 #
167164 # @driver.add_command(
168165 # method: :post,
169166 # url: 'session/:session_id/path/to/custom/url',
170167 # name: :test_command
171- # ) do
172- # def test_command(argument)
173- # execute(:test_command, {}, { dummy: argument })
174- # end
168+ # ) do |argument|
169+ # execute(:test_command, {}, { dummy: argument })
175170 # end
176171 # # Send a POST request to 'session/<session id>/path/to/custom/url'
177172 # # with body "{ dummy: 1 }" as JSON object. "1" is the argument.
178173 # # ':session_id' in the given 'url' is replaced with current 'session id'.
179174 # @driver.test_command(1)
180175 #
176+ # @example POST command with arguments (inline block)
177+ #
178+ # @driver.add_command(
179+ # method: :post,
180+ # url: 'session/:session_id/path/to/custom/url',
181+ # name: :test_command
182+ # ) { |argument| execute(:test_command, {}, { dummy: argument }) }
183+ # @driver.test_command(1)
184+ #
185+ # @example POST command with URL placeholders (do/end block)
181186 #
182187 # @driver.add_command(
183188 # method: :post,
184189 # url: 'session/:session_id/element/:id/custom/action',
185190 # name: :test_action_command
186- # ) do
187- # def test_action_command(element_id, action)
188- # execute(:test_action_command, {id: element_id}, { dummy_action: action })
189- # end
191+ # ) do |element_id, action|
192+ # execute(:test_action_command, {id: element_id}, { dummy_action: action })
190193 # end
191194 # # Send a POST request to 'session/<session id>/element/<element id>/custom/action'
192195 # # with body "{ dummy_action: #{action} }" as JSON object. "action" is the seconds argument.
@@ -195,10 +198,28 @@ def update_sending_request_to(protocol:, host:, port:, path:)
195198 # e = @driver.find_element :accessibility_id, 'an element'
196199 # @driver.test_action_command(e.id, 'action')
197200 #
201+ # @example POST command with URL placeholders (inline block)
202+ #
203+ # @driver.add_command(
204+ # method: :post,
205+ # url: 'session/:session_id/element/:id/custom/action',
206+ # name: :test_action_command
207+ # ) { |element_id, action| execute(:test_action_command, {id: element_id}, { dummy_action: action }) }
208+ # e = @driver.find_element :accessibility_id, 'an element'
209+ # @driver.test_action_command(e.id, 'action')
210+ #
198211 def add_command ( method :, url :, name :, &block )
199212 raise ::Appium ::Core ::Error ::ArgumentError , "Available method is either #{ AVAILABLE_METHODS } " unless AVAILABLE_METHODS . include? method
200213
201- @bridge . add_command method : method , url : url , name : name , &block
214+ ::Appium ::Logger . info "Overriding the command '#{ name } ' for '#{ url } '" if Bridge . extra_commands &.key? ( name )
215+
216+ # Use Selenium's Bridge.add_command to register the command and define the method.
217+ # When no block is given, create a default implementation that calls execute.
218+ block ||= proc { execute ( name ) }
219+ Bridge . add_command ( name , method , url , &block )
220+
221+ # Ensure the driver delegates the new method to bridge
222+ self . class . class_eval { def_delegator :@bridge , name } unless self . class . method_defined? ( name )
202223 end
203224
204225 ### Methods for Appium
0 commit comments