appium_lib_core 3.6.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +55 -1
- data/ci-jobs/functional/start-emulator.sh +1 -1
- data/ci-jobs/functional_test.yml +2 -2
- data/lib/appium_lib_core/android/device.rb +27 -1
- data/lib/appium_lib_core/android/device/screen.rb +5 -4
- data/lib/appium_lib_core/common/base/http_default.rb +20 -3
- data/lib/appium_lib_core/common/base/search_context.rb +0 -4
- data/lib/appium_lib_core/common/command/common.rb +4 -1
- data/lib/appium_lib_core/common/device/screen_record.rb +9 -3
- data/lib/appium_lib_core/device.rb +1 -1
- data/lib/appium_lib_core/driver.rb +47 -17
- data/lib/appium_lib_core/ios/xcuitest/device.rb +8 -1
- data/lib/appium_lib_core/ios/xcuitest/device/performance.rb +4 -2
- data/lib/appium_lib_core/ios/xcuitest/device/screen.rb +7 -6
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core/windows/device.rb +3 -15
- data/lib/appium_lib_core/windows/device/screen.rb +3 -8
- data/release_notes.md +42 -0
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: cd289d16dabe2e45527ce5f09ed786082f81001039217e4f3025f5666b084ac6
         | 
| 4 | 
            +
              data.tar.gz: b4a8cf9d7b0bb1f526bf910de4518796d2fcead98693a2bfa1c333eeb32a0d57
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 32aa153b24cf08f661783cc0a1bfe93ef2ddea8b3b7b5eeffc89416c0dda6d97942afe146aff4ee8cdb055093acdc6c992ea359dd0311aa64b96e77613e06719
         | 
| 7 | 
            +
              data.tar.gz: 67e5c83063987d25dd47cac816f5bedae955b5359bbe71dad7a4f54bcd7e047b2b09095eab08df748b06b44b3ee514113a1b652b7903e9a9ae90bd357736751e
         | 
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -10,7 +10,61 @@ Read `release_notes.md` for commit level details. | |
| 10 10 |  | 
| 11 11 | 
             
            ### Deprecations
         | 
| 12 12 |  | 
| 13 | 
            -
            ## [3. | 
| 13 | 
            +
            ## [3.10.0] - 2020-06-09
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            ### Enhancements
         | 
| 16 | 
            +
            - Remove deprecated `Selenium::WebDriver::Error::TimeOutError`
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ### Bug fixes
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            ### Deprecations
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            ## [3.9.0] - 2020-05-31
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            ### Enhancements
         | 
| 25 | 
            +
            - `capabilities:` is available in addition to `desired_capabilities:` and `caps:` as a capability
         | 
| 26 | 
            +
                ```ruby
         | 
| 27 | 
            +
                # case 1
         | 
| 28 | 
            +
                opts = { caps: { }, appium_lib: { } }
         | 
| 29 | 
            +
                @driver = Appium::Core.for(opts).start_driver
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # case 2
         | 
| 32 | 
            +
                opts = { capabilities: { }, appium_lib: { } }
         | 
| 33 | 
            +
                @driver = Appium::Core.for(opts).start_driver
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # case 3
         | 
| 36 | 
            +
                opts = { desired_capabilities: { }, appium_lib: { } }
         | 
| 37 | 
            +
                @driver = Appium::Core.for(opts).start_driver
         | 
| 38 | 
            +
                ```
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            ### Bug fixes
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            ### Deprecations
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            ## [3.8.0] - 2020-05-17
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            ### Enhancements
         | 
| 47 | 
            +
            - Add options for `start_recording_screen`
         | 
| 48 | 
            +
                - `file_field_name`, `form_fields` and `headers` are available since Appium 1.18.0
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            ### Bug fixes
         | 
| 51 | 
            +
            - Fix `x-idempotency-key` header to add it only in new session request (https://github.com/appium/ruby_lib_core/issues/262)
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            ### Deprecations
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            ## [3.7.0] - 2020-04-18
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            ### Enhancements
         | 
| 58 | 
            +
            - Add `x-idempotency-key` header support (https://github.com/appium/appium-base-driver/pull/400)
         | 
| 59 | 
            +
                - Can disable the header with `enable_idempotency_header: false` in `appium_lib` capability. Defaults to `true`.
         | 
| 60 | 
            +
            - Add chrome devtools endpoint which is available chrome module in Selenium Ruby binding 
         | 
| 61 | 
            +
                - https://github.com/appium/appium-base-driver/pull/405
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            ### Bug fixes
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            ### Deprecations
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            ## [3.6.1, 3.6.0] - 2020-03-15
         | 
| 14 68 |  | 
| 15 69 | 
             
            ### Enhancements
         | 
| 16 70 | 
             
            - Add screen record feature for Windows driver (https://github.com/appium/appium-windows-driver/pull/66)
         | 
| @@ -18,7 +18,7 @@ echo ${ANDROID_HOME}/emulator/emulator -list-avds | |
| 18 18 | 
             
            echo "Starting emulator"
         | 
| 19 19 |  | 
| 20 20 | 
             
            # Start emulator in background
         | 
| 21 | 
            -
            nohup ${ANDROID_HOME}/emulator/emulator -avd testemulator -no-boot-anim -no-snapshot > /dev/null 2>&1 &
         | 
| 21 | 
            +
            nohup ${ANDROID_HOME}/emulator/emulator -avd testemulator -accel auto -no-boot-anim -no-snapshot > /dev/null 2>&1 &
         | 
| 22 22 | 
             
            ${ANDROID_HOME}/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
         | 
| 23 23 |  | 
| 24 24 | 
             
            ${ANDROID_HOME}/platform-tools/adb devices
         | 
    
        data/ci-jobs/functional_test.yml
    CHANGED
    
    | @@ -2,8 +2,8 @@ | |
| 2 2 | 
             
            parameters:
         | 
| 3 3 | 
             
              vmImage: 'macOS-10.15'
         | 
| 4 4 | 
             
              vmImageForIOS: 'macOS-10.15' # Not sure the reason, but macOS 10.14 instance raises no info.plist error
         | 
| 5 | 
            -
              xcodeForIOS: 11. | 
| 6 | 
            -
              xcodeForTVOS: 11. | 
| 5 | 
            +
              xcodeForIOS: 11.5
         | 
| 6 | 
            +
              xcodeForTVOS: 11.5
         | 
| 7 7 | 
             
              androidSDK: 29
         | 
| 8 8 | 
             
              appiumVersion: 'beta'
         | 
| 9 9 | 
             
              ignoreVersionSkip: true
         | 
| @@ -213,7 +213,7 @@ module Appium | |
| 213 213 | 
             
                    #   @driver.get_performance_data package_name: package_name, data_type: data_type, data_read_timeout: 2
         | 
| 214 214 | 
             
                    #
         | 
| 215 215 |  | 
| 216 | 
            -
                    # @!method start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT', force_restart: nil, video_size: nil, time_limit: '180', bit_rate: '4000000', bug_report: nil)
         | 
| 216 | 
            +
                    # @!method start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT', file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil, video_size: nil, time_limit: '180', bit_rate: '4000000', bug_report: nil)
         | 
| 217 217 | 
             
                    # @param [String] remote_path The path to the remote location, where the resulting video should be uploaded.
         | 
| 218 218 | 
             
                    #                             The following protocols are supported: http/https, ftp.
         | 
| 219 219 | 
             
                    #                             Null or empty string value (the default setting) means the content of resulting
         | 
| @@ -225,6 +225,11 @@ module Appium | |
| 225 225 | 
             
                    # @param [String] user The name of the user for the remote authentication.
         | 
| 226 226 | 
             
                    # @param [String] pass The password for the remote authentication.
         | 
| 227 227 | 
             
                    # @param [String] method The http multipart upload method name. The 'PUT' one is used by default.
         | 
| 228 | 
            +
                    # @param [String] file_field_name The name of the form field containing the binary payload in multipart/form-data
         | 
| 229 | 
            +
                    #                             requests since Appium 1.18.0. Defaults to 'file'.
         | 
| 230 | 
            +
                    # @param [Array<Hash, Array<String>>] form_fields The form fields mapping in multipart/form-data requests since Appium 1.18.0.
         | 
| 231 | 
            +
                    #                             If any entry has the same key in this mapping, then it is going to be ignored.
         | 
| 232 | 
            +
                    # @param [Hash] headers The additional headers in multipart/form-data requests since Appium 1.18.0.
         | 
| 228 233 | 
             
                    # @param [Boolean] force_restart Whether to try to catch and upload/return the currently running screen recording
         | 
| 229 234 | 
             
                    #                                 (+false+, the default setting on server) or ignore the result of it
         | 
| 230 235 | 
             
                    #                                 and start a new recording immediately (+true+).
         | 
| @@ -245,6 +250,8 @@ module Appium | |
| 245 250 | 
             
                    # @param [Boolean] bug_report Set it to +true+ in order to display additional information on the video overlay,
         | 
| 246 251 | 
             
                    #                             such as a timestamp, that is helpful in videos captured to illustrate bugs.
         | 
| 247 252 | 
             
                    #                             This option is only supported since API level 27 (Android P).
         | 
| 253 | 
            +
                    # @return [String] Base64 encoded content of the recorded media file or an empty string
         | 
| 254 | 
            +
                    #                  if the file has been successfully uploaded to a remote location (depends on the actual options)
         | 
| 248 255 | 
             
                    #
         | 
| 249 256 | 
             
                    # @example
         | 
| 250 257 | 
             
                    #
         | 
| @@ -283,6 +290,19 @@ module Appium | |
| 283 290 | 
             
                    #   @driver.finger_print 1
         | 
| 284 291 | 
             
                    #
         | 
| 285 292 |  | 
| 293 | 
            +
                    # @!method execute_cdp(cmd, params)
         | 
| 294 | 
            +
                    #     Execute Chrome Devtools protocol commands
         | 
| 295 | 
            +
                    #     https://chromedevtools.github.io/devtools-protocol
         | 
| 296 | 
            +
                    #
         | 
| 297 | 
            +
                    # @param [String] cmd The name of command
         | 
| 298 | 
            +
                    # @param [Hash] params The parameter for the command as hash.
         | 
| 299 | 
            +
                    #
         | 
| 300 | 
            +
                    # @example
         | 
| 301 | 
            +
                    #
         | 
| 302 | 
            +
                    #   @driver.execute_cdp 'Page.captureScreenshot', { quality: 50, format: 'jpeg' }
         | 
| 303 | 
            +
                    #   @driver.execute_cdp 'Page.getResourceTree'
         | 
| 304 | 
            +
                    #
         | 
| 305 | 
            +
             | 
| 286 306 | 
             
                    ####
         | 
| 287 307 | 
             
                    ## class << self
         | 
| 288 308 | 
             
                    ####
         | 
| @@ -391,6 +411,12 @@ module Appium | |
| 391 411 | 
             
                          end
         | 
| 392 412 | 
             
                        end
         | 
| 393 413 |  | 
| 414 | 
            +
                        ::Appium::Core::Device.add_endpoint_method(:execute_cdp) do
         | 
| 415 | 
            +
                          def execute_cdp(cmd, **params)
         | 
| 416 | 
            +
                            execute :chrome_send_command, {}, { cmd: cmd, params: params }
         | 
| 417 | 
            +
                          end
         | 
| 418 | 
            +
                        end
         | 
| 419 | 
            +
             | 
| 394 420 | 
             
                        Screen.add_methods
         | 
| 395 421 | 
             
                        Performance.add_methods
         | 
| 396 422 | 
             
                        Network.add_methods
         | 
| @@ -25,11 +25,13 @@ module Appium | |
| 25 25 | 
             
                        end
         | 
| 26 26 |  | 
| 27 27 | 
             
                        ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
         | 
| 28 | 
            -
                           | 
| 29 | 
            -
             | 
| 28 | 
            +
                          def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
         | 
| 29 | 
            +
                                                     file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil,
         | 
| 30 30 | 
             
                                                     video_size: nil, time_limit: '180', bit_rate: nil, bug_report: nil)
         | 
| 31 31 | 
             
                            option = ::Appium::Core::Base::Device::ScreenRecord.new(
         | 
| 32 | 
            -
                              remote_path: remote_path, user: user, pass: pass, method: method, | 
| 32 | 
            +
                              remote_path: remote_path, user: user, pass: pass, method: method,
         | 
| 33 | 
            +
                              file_field_name: file_field_name, form_fields: form_fields, headers: headers,
         | 
| 34 | 
            +
                              force_restart: force_restart
         | 
| 33 35 | 
             
                            ).upload_option
         | 
| 34 36 |  | 
| 35 37 | 
             
                            option[:videoSize] = video_size unless video_size.nil?
         | 
| @@ -44,7 +46,6 @@ module Appium | |
| 44 46 |  | 
| 45 47 | 
             
                            execute(:start_recording_screen, {}, { options: option })
         | 
| 46 48 | 
             
                          end
         | 
| 47 | 
            -
                          # rubocop:enable Metrics/ParameterLists
         | 
| 48 49 | 
             
                        end
         | 
| 49 50 | 
             
                      end
         | 
| 50 51 | 
             
                    end # module Screen
         | 
| @@ -12,12 +12,20 @@ | |
| 12 12 | 
             
            # See the License for the specific language governing permissions and
         | 
| 13 13 | 
             
            # limitations under the License.
         | 
| 14 14 |  | 
| 15 | 
            +
            require 'securerandom'
         | 
| 16 | 
            +
             | 
| 15 17 | 
             
            require_relative '../../version'
         | 
| 16 18 |  | 
| 17 19 | 
             
            module Appium
         | 
| 18 20 | 
             
              module Core
         | 
| 19 21 | 
             
                class Base
         | 
| 20 22 | 
             
                  module Http
         | 
| 23 | 
            +
                    module RequestHeaders
         | 
| 24 | 
            +
                      KEYS = {
         | 
| 25 | 
            +
                        idempotency: 'X-Idempotency-Key'
         | 
| 26 | 
            +
                      }.freeze
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 21 29 | 
             
                    class Default < Selenium::WebDriver::Remote::Http::Default
         | 
| 22 30 | 
             
                      DEFAULT_HEADERS = {
         | 
| 23 31 | 
             
                        'Accept' => CONTENT_TYPE,
         | 
| @@ -26,6 +34,14 @@ module Appium | |
| 26 34 | 
             
                          "appium/ruby_lib_core/#{VERSION} (#{::Selenium::WebDriver::Remote::Http::Common::DEFAULT_HEADERS['User-Agent']})"
         | 
| 27 35 | 
             
                      }.freeze
         | 
| 28 36 |  | 
| 37 | 
            +
                      attr_reader :additional_headers
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                      def initialize(open_timeout: nil, read_timeout: nil)
         | 
| 40 | 
            +
                        @open_timeout = open_timeout
         | 
| 41 | 
            +
                        @read_timeout = read_timeout
         | 
| 42 | 
            +
                        @additional_headers = {}
         | 
| 43 | 
            +
                      end
         | 
| 44 | 
            +
             | 
| 29 45 | 
             
                      # Update <code>server_url</code> provided when ruby_lib _core created a default http client.
         | 
| 30 46 | 
             
                      # Set <code>@http</code> as nil to re-create http client for the <code>server_url</code>
         | 
| 31 47 | 
             
                      #
         | 
| @@ -65,19 +81,20 @@ module Appium | |
| 65 81 | 
             
                      def call(verb, url, command_hash)
         | 
| 66 82 | 
             
                        url      = server_url.merge(url) unless url.is_a?(URI)
         | 
| 67 83 | 
             
                        headers  = DEFAULT_HEADERS.dup
         | 
| 84 | 
            +
                        headers  = headers.merge @additional_headers unless @additional_headers.empty?
         | 
| 68 85 | 
             
                        headers['Cache-Control'] = 'no-cache' if verb == :get
         | 
| 69 86 |  | 
| 70 87 | 
             
                        if command_hash
         | 
| 71 88 | 
             
                          payload                   = JSON.generate(command_hash)
         | 
| 72 89 | 
             
                          headers['Content-Length'] = payload.bytesize.to_s if [:post, :put].include?(verb)
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                          ::Appium::Logger.info("   >>> #{url} | #{payload}")
         | 
| 75 | 
            -
                          ::Appium::Logger.debug("     > #{headers.inspect}")
         | 
| 76 90 | 
             
                        elsif verb == :post
         | 
| 77 91 | 
             
                          payload = '{}'
         | 
| 78 92 | 
             
                          headers['Content-Length'] = '2'
         | 
| 79 93 | 
             
                        end
         | 
| 80 94 |  | 
| 95 | 
            +
                        ::Appium::Logger.info("   >>> #{url} | #{payload}")
         | 
| 96 | 
            +
                        ::Appium::Logger.info("     > #{headers.inspect}")
         | 
| 97 | 
            +
             | 
| 81 98 | 
             
                        request verb, url, headers, payload
         | 
| 82 99 | 
             
                      end
         | 
| 83 100 | 
             
                    end
         | 
| @@ -135,8 +135,6 @@ module Appium | |
| 135 135 | 
             
                      by = _set_by_from_finders(how)
         | 
| 136 136 | 
             
                      begin
         | 
| 137 137 | 
             
                        bridge.find_element_by by, what.to_s, ref
         | 
| 138 | 
            -
                      rescue Selenium::WebDriver::Error::TimeOutError # will deprecate
         | 
| 139 | 
            -
                        raise Selenium::WebDriver::Error::NoSuchElementError
         | 
| 140 138 | 
             
                      rescue Selenium::WebDriver::Error::TimeoutError
         | 
| 141 139 | 
             
                        raise Selenium::WebDriver::Error::NoSuchElementError
         | 
| 142 140 | 
             
                      end
         | 
| @@ -152,8 +150,6 @@ module Appium | |
| 152 150 | 
             
                      by = _set_by_from_finders(how)
         | 
| 153 151 | 
             
                      begin
         | 
| 154 152 | 
             
                        bridge.find_elements_by by, what.to_s, ref
         | 
| 155 | 
            -
                      rescue Selenium::WebDriver::Error::TimeOutError # will deprecate
         | 
| 156 | 
            -
                        []
         | 
| 157 153 | 
             
                      rescue Selenium::WebDriver::Error::TimeoutError
         | 
| 158 154 | 
             
                        []
         | 
| 159 155 | 
             
                      end
         | 
| @@ -94,7 +94,10 @@ module Appium | |
| 94 94 | 
             
                    gsm_voice:                  [:post, 'session/:session_id/appium/device/gsm_voice'],
         | 
| 95 95 | 
             
                    set_network_speed:          [:post, 'session/:session_id/appium/device/network_speed'],
         | 
| 96 96 | 
             
                    set_power_capacity:         [:post, 'session/:session_id/appium/device/power_capacity'],
         | 
| 97 | 
            -
                    set_power_ac:               [:post, 'session/:session_id/appium/device/power_ac']
         | 
| 97 | 
            +
                    set_power_ac:               [:post, 'session/:session_id/appium/device/power_ac'],
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    # For chromium: https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/server/http_handler.cc
         | 
| 100 | 
            +
                    chrome_send_command:        [:post, 'session/:session_id/goog/cdp/execute']
         | 
| 98 101 | 
             
                  }.freeze
         | 
| 99 102 |  | 
| 100 103 | 
             
                  COMMAND_IOS = {
         | 
| @@ -25,7 +25,8 @@ module Appium | |
| 25 25 |  | 
| 26 26 | 
             
                      METHOD = %w(POST PUT).freeze
         | 
| 27 27 |  | 
| 28 | 
            -
                      def initialize(remote_path: nil, user: nil, pass: nil, method: 'PUT', | 
| 28 | 
            +
                      def initialize(remote_path: nil, user: nil, pass: nil, method: 'PUT',
         | 
| 29 | 
            +
                                     file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil)
         | 
| 29 30 | 
             
                        @upload_option = if remote_path.nil?
         | 
| 30 31 | 
             
                                           {}
         | 
| 31 32 | 
             
                                         else
         | 
| @@ -36,6 +37,9 @@ module Appium | |
| 36 37 | 
             
                                           option[:user] = user unless user.nil?
         | 
| 37 38 | 
             
                                           option[:pass] = pass unless pass.nil?
         | 
| 38 39 | 
             
                                           option[:method] = method
         | 
| 40 | 
            +
                                           option[:fileFieldName] = file_field_name unless file_field_name.nil?
         | 
| 41 | 
            +
                                           option[:formFields] = form_fields unless form_fields.nil?
         | 
| 42 | 
            +
                                           option[:headers] = headers unless headers.nil?
         | 
| 39 43 | 
             
                                           option
         | 
| 40 44 | 
             
                                         end
         | 
| 41 45 |  | 
| @@ -47,9 +51,11 @@ module Appium | |
| 47 51 | 
             
                      end
         | 
| 48 52 |  | 
| 49 53 | 
             
                      module Command
         | 
| 50 | 
            -
                        def stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT' | 
| 54 | 
            +
                        def stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
         | 
| 55 | 
            +
                                                  file_field_name: nil, form_fields: nil, headers: nil)
         | 
| 51 56 | 
             
                          option = ::Appium::Core::Base::Device::ScreenRecord.new(
         | 
| 52 | 
            -
                            remote_path: remote_path, user: user, pass: pass, method: method
         | 
| 57 | 
            +
                            remote_path: remote_path, user: user, pass: pass, method: method,
         | 
| 58 | 
            +
                            file_field_name: file_field_name, form_fields: form_fields, headers: headers
         | 
| 53 59 | 
             
                          ).upload_option
         | 
| 54 60 |  | 
| 55 61 | 
             
                          params = option.empty? ? {} : { options: option }
         | 
| @@ -34,11 +34,12 @@ module Appium | |
| 34 34 | 
             
                class Options
         | 
| 35 35 | 
             
                  attr_reader :custom_url, :default_wait, :export_session, :export_session_path,
         | 
| 36 36 | 
             
                              :port, :wait_timeout, :wait_interval, :listener,
         | 
| 37 | 
            -
                              :direct_connect
         | 
| 37 | 
            +
                              :direct_connect, :enable_idempotency_header
         | 
| 38 38 |  | 
| 39 39 | 
             
                  def initialize(appium_lib_opts)
         | 
| 40 40 | 
             
                    @custom_url = appium_lib_opts.fetch :server_url, nil
         | 
| 41 41 | 
             
                    @default_wait = appium_lib_opts.fetch :wait, Driver::DEFAULT_IMPLICIT_WAIT
         | 
| 42 | 
            +
                    @enable_idempotency_header = appium_lib_opts.fetch :enable_idempotency_header, true
         | 
| 42 43 |  | 
| 43 44 | 
             
                    # bump current session id into a particular file
         | 
| 44 45 | 
             
                    @export_session = appium_lib_opts.fetch :export_session, false
         | 
| @@ -104,6 +105,13 @@ module Appium | |
| 104 105 | 
             
                  # @return [Appium::Core::Base::Http::Default] the http client
         | 
| 105 106 | 
             
                  attr_reader :http_client
         | 
| 106 107 |  | 
| 108 | 
            +
                  # Return if adding 'x-idempotency-key' header is enabled for each new session request.
         | 
| 109 | 
            +
                  # Following commands should not have the key.
         | 
| 110 | 
            +
                  # The key is unique for each http client instance. Defaults to <code>true</code>
         | 
| 111 | 
            +
                  # https://github.com/appium/appium-base-driver/pull/400
         | 
| 112 | 
            +
                  # @return [Bool]
         | 
| 113 | 
            +
                  attr_reader :enable_idempotency_header
         | 
| 114 | 
            +
             | 
| 107 115 | 
             
                  # Device type to request from the appium server
         | 
| 108 116 | 
             
                  # @return [Symbol] :android and :ios, for example
         | 
| 109 117 | 
             
                  attr_reader :device
         | 
| @@ -114,11 +122,11 @@ module Appium | |
| 114 122 | 
             
                  attr_reader :automation_name
         | 
| 115 123 |  | 
| 116 124 | 
             
                  # Custom URL for the selenium server. If set this attribute, ruby_lib_core try to handshake to the custom url.<br>
         | 
| 117 | 
            -
                  # Defaults to false. Then try to connect to <code>http://127.0.0.1:#{port}/wd/hub | 
| 125 | 
            +
                  # Defaults to false. Then try to connect to <code>http://127.0.0.1:#{port}/wd/hub</code>.
         | 
| 118 126 | 
             
                  # @return [String]
         | 
| 119 127 | 
             
                  attr_reader :custom_url
         | 
| 120 128 |  | 
| 121 | 
            -
                  # Export session id to textfile in /tmp for 3rd party tools. False  | 
| 129 | 
            +
                  # Export session id to textfile in /tmp for 3rd party tools. False by default.
         | 
| 122 130 | 
             
                  # @return [Boolean]
         | 
| 123 131 | 
             
                  attr_reader :export_session
         | 
| 124 132 | 
             
                  # @return [String] By default, session id is exported in '/tmp/appium_lib_session'
         | 
| @@ -174,7 +182,9 @@ module Appium | |
| 174 182 |  | 
| 175 183 | 
             
                  # Creates a new driver and extend particular methods
         | 
| 176 184 | 
             
                  # @param [Hash] opts A options include capabilities for the Appium Server and for the client.
         | 
| 177 | 
            -
                  # @option opts [Hash] :caps Appium capabilities. | 
| 185 | 
            +
                  # @option opts [Hash] :caps Appium capabilities.
         | 
| 186 | 
            +
                  # @option opts [Hash] :capabilities The same as :caps.
         | 
| 187 | 
            +
                  #                                   This param is for compatibility with Selenium WebDriver format
         | 
| 178 188 | 
             
                  # @option opts [Hash] :desired_capabilities The same as :caps.
         | 
| 179 189 | 
             
                  #                                           This param is for compatibility with Selenium WebDriver format
         | 
| 180 190 | 
             
                  # @option opts [Appium::Core::Options] :appium_lib Capabilities affect only ruby client
         | 
| @@ -187,8 +197,8 @@ module Appium | |
| 187 197 | 
             
                  #
         | 
| 188 198 | 
             
                  #     # format 1
         | 
| 189 199 | 
             
                  #     @core = Appium::Core.for caps: {...}, appium_lib: {...}
         | 
| 190 | 
            -
                  #     # format 2. 'desired_capabilities:' is also available instead of 'caps:'. | 
| 191 | 
            -
                  #     @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub",  | 
| 200 | 
            +
                  #     # format 2. 'capabilities:' or 'desired_capabilities:' is also available instead of 'caps:'.
         | 
| 201 | 
            +
                  #     @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub", capabilities: {...}, appium_lib: {...}
         | 
| 192 202 | 
             
                  #     # format 3. 'appium_lib: {...}' can be blank
         | 
| 193 203 | 
             
                  #     @core = Appium::Core.for url: "http://127.0.0.1:8080/wd/hub", desired_capabilities: {...}
         | 
| 194 204 | 
             
                  #
         | 
| @@ -218,9 +228,9 @@ module Appium | |
| 218 228 | 
             
                  #     @core.start_driver # Connect to 'http://127.0.0.1:8080/wd/hub' because of 'port: 8080'
         | 
| 219 229 | 
             
                  #
         | 
| 220 230 | 
             
                  #     # Start iOS driver with .zip file over HTTP
         | 
| 221 | 
            -
                  #     #  'desired_capabilities:' is also available instead of 'caps:'. Either is fine.
         | 
| 231 | 
            +
                  #     #  'desired_capabilities:' or 'capabilities:' is also available instead of 'caps:'. Either is fine.
         | 
| 222 232 | 
             
                  #     opts = {
         | 
| 223 | 
            -
                  #               | 
| 233 | 
            +
                  #              capabilities: {
         | 
| 224 234 | 
             
                  #                platformName: :ios,
         | 
| 225 235 | 
             
                  #                platformVersion: '11.0',
         | 
| 226 236 | 
             
                  #                deviceName: 'iPhone Simulator',
         | 
| @@ -342,9 +352,17 @@ module Appium | |
| 342 352 | 
             
                                   http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })
         | 
| 343 353 | 
             
                    @custom_url ||= server_url || "http://127.0.0.1:#{@port}/wd/hub"
         | 
| 344 354 |  | 
| 345 | 
            -
                     | 
| 346 | 
            -
             | 
| 347 | 
            -
             | 
| 355 | 
            +
                    @http_client = get_http_client http_client: http_client_ops.delete(:http_client),
         | 
| 356 | 
            +
                                                   open_timeout: http_client_ops.delete(:open_timeout),
         | 
| 357 | 
            +
                                                   read_timeout: http_client_ops.delete(:read_timeout)
         | 
| 358 | 
            +
             | 
| 359 | 
            +
                    if @enable_idempotency_header
         | 
| 360 | 
            +
                      if @http_client.instance_variable_defined? :@additional_headers
         | 
| 361 | 
            +
                        @http_client.additional_headers[Appium::Core::Base::Http::RequestHeaders::KEYS[:idempotency]] = SecureRandom.uuid
         | 
| 362 | 
            +
                      else
         | 
| 363 | 
            +
                        ::Appium::Logger.warn 'No additional_headers attribute in this http client instance'
         | 
| 364 | 
            +
                      end
         | 
| 365 | 
            +
                    end
         | 
| 348 366 |  | 
| 349 367 | 
             
                    begin
         | 
| 350 368 | 
             
                      # included https://github.com/SeleniumHQ/selenium/blob/43f8b3f66e7e01124eff6a5805269ee441f65707/rb/lib/selenium/webdriver/remote/driver.rb#L29
         | 
| @@ -364,6 +382,11 @@ module Appium | |
| 364 382 | 
             
                      raise "ERROR: Unable to connect to Appium. Is the server running on #{@custom_url}?"
         | 
| 365 383 | 
             
                    end
         | 
| 366 384 |  | 
| 385 | 
            +
                    if @http_client.instance_variable_defined? :@additional_headers
         | 
| 386 | 
            +
                      # We only need the key for a new session request. Should remove it for other following commands.
         | 
| 387 | 
            +
                      @http_client.additional_headers.delete Appium::Core::Base::Http::RequestHeaders::KEYS[:idempotency]
         | 
| 388 | 
            +
                    end
         | 
| 389 | 
            +
             | 
| 367 390 | 
             
                    # If "automationName" is set only server side, this method set "automationName" attribute into @automation_name.
         | 
| 368 391 | 
             
                    # Since @automation_name is set only client side before start_driver is called.
         | 
| 369 392 | 
             
                    set_automation_name_if_nil
         | 
| @@ -375,12 +398,14 @@ module Appium | |
| 375 398 |  | 
| 376 399 | 
             
                  private
         | 
| 377 400 |  | 
| 378 | 
            -
                  def  | 
| 379 | 
            -
                     | 
| 401 | 
            +
                  def get_http_client(http_client: nil, open_timeout: nil, read_timeout: nil)
         | 
| 402 | 
            +
                    client = http_client || Appium::Core::Base::Http::Default.new
         | 
| 380 403 |  | 
| 381 404 | 
             
                    # open_timeout and read_timeout are explicit wait.
         | 
| 382 | 
            -
                     | 
| 383 | 
            -
                     | 
| 405 | 
            +
                    client.open_timeout = open_timeout if open_timeout
         | 
| 406 | 
            +
                    client.read_timeout = read_timeout if read_timeout
         | 
| 407 | 
            +
             | 
| 408 | 
            +
                    client
         | 
| 384 409 | 
             
                  end
         | 
| 385 410 |  | 
| 386 411 | 
             
                  # Ignore setting default wait if the target driver has no implementation
         | 
| @@ -518,7 +543,10 @@ module Appium | |
| 518 543 | 
             
                  def validate_keys(opts)
         | 
| 519 544 | 
             
                    flatten_ops = flatten_hash_keys(opts)
         | 
| 520 545 |  | 
| 521 | 
            -
                     | 
| 546 | 
            +
                    # FIXME: Remove 'desired_capabilities' in the next major Selenium update
         | 
| 547 | 
            +
                    unless opts.member?(:caps) || opts.member?(:capabilities) || opts.member?(:desired_capabilities)
         | 
| 548 | 
            +
                      raise Error::NoCapabilityError
         | 
| 549 | 
            +
                    end
         | 
| 522 550 |  | 
| 523 551 | 
             
                    if !opts.member?(:appium_lib) && flatten_ops.member?(:appium_lib)
         | 
| 524 552 | 
             
                      raise Error::CapabilityStructureError, 'Please check the value of appium_lib in the capability'
         | 
| @@ -539,7 +567,8 @@ module Appium | |
| 539 567 |  | 
| 540 568 | 
             
                  # @private
         | 
| 541 569 | 
             
                  def get_caps(opts)
         | 
| 542 | 
            -
                     | 
| 570 | 
            +
                    # FIXME: Remove 'desired_capabilities' in the next major Selenium update
         | 
| 571 | 
            +
                    Core::Base::Capabilities.create_capabilities(opts[:caps] || opts[:capabilities] || opts[:desired_capabilities] || {})
         | 
| 543 572 | 
             
                  end
         | 
| 544 573 |  | 
| 545 574 | 
             
                  # @private
         | 
| @@ -570,6 +599,7 @@ module Appium | |
| 570 599 | 
             
                    opts = Options.new appium_lib_opts
         | 
| 571 600 |  | 
| 572 601 | 
             
                    @custom_url ||= opts.custom_url # Keep existence capability if it's already provided
         | 
| 602 | 
            +
                    @enable_idempotency_header = opts.enable_idempotency_header
         | 
| 573 603 |  | 
| 574 604 | 
             
                    @default_wait = opts.default_wait
         | 
| 575 605 |  | 
| @@ -51,7 +51,7 @@ module Appium | |
| 51 51 | 
             
                      #
         | 
| 52 52 |  | 
| 53 53 | 
             
                      # @since Appium 1.9.1
         | 
| 54 | 
            -
                      # @!method start_recording_screen(remote_path: nil, user: nil, pass: nil, method: nil, force_restart: nil, video_type: 'mjpeg', video_fps: nil, time_limit: '180', video_quality:  | 
| 54 | 
            +
                      # @!method start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT', file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil, video_type: 'mjpeg', video_fps: nil, time_limit: '180', video_quality: nil, video_scale: nil, video_filters: nil, pixel_format: nil)
         | 
| 55 55 | 
             
                      #
         | 
| 56 56 | 
             
                      # Record the display of devices running iOS Simulator since Xcode 9 or real devices since iOS 11
         | 
| 57 57 | 
             
                      # (ffmpeg utility is required: 'brew install ffmpeg').
         | 
| @@ -68,6 +68,11 @@ module Appium | |
| 68 68 | 
             
                      # @param [String] user The name of the user for the remote authentication.
         | 
| 69 69 | 
             
                      # @param [String] pass The password for the remote authentication.
         | 
| 70 70 | 
             
                      # @param [String] method The http multipart upload method name. The 'PUT' one is used by default.
         | 
| 71 | 
            +
                      # @param [String] file_field_name The name of the form field containing the binary payload in multipart/form-data
         | 
| 72 | 
            +
                      #                             requests since Appium 1.18.0. Defaults to 'file'.
         | 
| 73 | 
            +
                      # @param [Array<Hash, Array<String>>] form_fields The form fields mapping in multipart/form-data requests since Appium 1.18.0.
         | 
| 74 | 
            +
                      #                             If any entry has the same key in this mapping, then it is going to be ignored.
         | 
| 75 | 
            +
                      # @param [Hash] headers The additional headers in multipart/form-data requests since Appium 1.18.0.
         | 
| 71 76 | 
             
                      # @param [Boolean] force_restart Whether to try to catch and upload/return the currently running screen recording
         | 
| 72 77 | 
             
                      #                                (+false+, the default setting on server) or ignore the result of it
         | 
| 73 78 | 
             
                      #                                and start a new recording immediately (+true+).
         | 
| @@ -91,6 +96,8 @@ module Appium | |
| 91 96 | 
             
                      #                             - https://www.reddit.com/r/linux4noobs/comments/671z6b/width_not_divisible_by_2_error_when_using_ffmpeg/
         | 
| 92 97 | 
             
                      # @param [String] pixel_format Output pixel format. Run +ffmpeg -pix_fmts+ to list possible values.
         | 
| 93 98 | 
             
                      #                              For Quicktime compatibility, set to "yuv420p" along with videoType: "libx264".
         | 
| 99 | 
            +
                      # @return [String] Base64 encoded content of the recorded media file or an empty string
         | 
| 100 | 
            +
                      #                  if the file has been successfully uploaded to a remote location (depends on the actual options)
         | 
| 94 101 | 
             
                      #
         | 
| 95 102 | 
             
                      # @example
         | 
| 96 103 | 
             
                      #
         | 
| @@ -32,9 +32,11 @@ module Appium | |
| 32 32 |  | 
| 33 33 | 
             
                          ::Appium::Core::Device.add_endpoint_method(:get_performance_record) do
         | 
| 34 34 | 
             
                            def get_performance_record(save_file_path: './performance', profile_name: 'Activity Monitor',
         | 
| 35 | 
            -
                                                       remote_path: nil, user: nil, pass: nil, method: 'PUT' | 
| 35 | 
            +
                                                       remote_path: nil, user: nil, pass: nil, method: 'PUT',
         | 
| 36 | 
            +
                                                       file_field_name: nil, form_fields: nil, headers: nil)
         | 
| 36 37 | 
             
                              option = ::Appium::Core::Base::Device::ScreenRecord.new(
         | 
| 37 | 
            -
                                remote_path: remote_path, user: user, pass: pass, method: method
         | 
| 38 | 
            +
                                remote_path: remote_path, user: user, pass: pass, method: method,
         | 
| 39 | 
            +
                                file_field_name: file_field_name, form_fields: form_fields, headers: headers
         | 
| 38 40 | 
             
                              ).upload_option
         | 
| 39 41 |  | 
| 40 42 | 
             
                              option[:profileName] = profile_name
         | 
| @@ -20,18 +20,20 @@ module Appium | |
| 20 20 | 
             
                      module Screen
         | 
| 21 21 | 
             
                        def self.add_methods
         | 
| 22 22 | 
             
                          ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
         | 
| 23 | 
            -
                             | 
| 24 | 
            -
             | 
| 25 | 
            -
                                                       video_type: 'mjpeg', time_limit: '180', video_quality:  | 
| 23 | 
            +
                            def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
         | 
| 24 | 
            +
                                                       file_field_name: nil, form_fields: nil, headers: nil, force_restart: nil,
         | 
| 25 | 
            +
                                                       video_type: 'mjpeg', time_limit: '180', video_quality: nil,
         | 
| 26 26 | 
             
                                                       video_fps: nil, video_scale: nil, video_filters: nil, pixel_format: nil)
         | 
| 27 27 | 
             
                              option = ::Appium::Core::Base::Device::ScreenRecord.new(
         | 
| 28 | 
            -
                                remote_path: remote_path, user: user, pass: pass, method: method, | 
| 28 | 
            +
                                remote_path: remote_path, user: user, pass: pass, method: method,
         | 
| 29 | 
            +
                                file_field_name: file_field_name, form_fields: form_fields, headers: headers,
         | 
| 30 | 
            +
                                force_restart: force_restart
         | 
| 29 31 | 
             
                              ).upload_option
         | 
| 30 32 |  | 
| 31 33 | 
             
                              option[:videoType] = video_type
         | 
| 32 34 | 
             
                              option[:timeLimit] = time_limit
         | 
| 33 | 
            -
                              option[:videoQuality] = video_quality
         | 
| 34 35 |  | 
| 36 | 
            +
                              option[:videoQuality] = video_quality unless video_quality.nil?
         | 
| 35 37 | 
             
                              option[:videoFps] = video_fps unless video_fps.nil?
         | 
| 36 38 | 
             
                              option[:videoScale] = video_scale unless video_scale.nil?
         | 
| 37 39 | 
             
                              option[:videoFilters] = video_filters unless video_filters.nil?
         | 
| @@ -39,7 +41,6 @@ module Appium | |
| 39 41 |  | 
| 40 42 | 
             
                              execute(:start_recording_screen, {}, { options: option })
         | 
| 41 43 | 
             
                            end
         | 
| 42 | 
            -
                            # rubocop:enable Metrics/ParameterLists
         | 
| 43 44 | 
             
                          end
         | 
| 44 45 | 
             
                        end
         | 
| 45 46 | 
             
                      end # module Screen
         | 
| @@ -14,7 +14,7 @@ | |
| 14 14 |  | 
| 15 15 | 
             
            module Appium
         | 
| 16 16 | 
             
              module Core
         | 
| 17 | 
            -
                VERSION = '3. | 
| 18 | 
            -
                DATE    = '2020- | 
| 17 | 
            +
                VERSION = '3.10.0' unless defined? ::Appium::Core::VERSION
         | 
| 18 | 
            +
                DATE    = '2020-06-09' unless defined? ::Appium::Core::DATE
         | 
| 19 19 | 
             
              end
         | 
| 20 20 | 
             
            end
         | 
| @@ -29,21 +29,8 @@ module Appium | |
| 29 29 | 
             
                    # This method requires FFMPEG (https://www.ffmpeg.org/download.html) to be installed and present in PATH.
         | 
| 30 30 | 
             
                    # The resulting video uses H264 codec and is ready to be played by media players built-in into web browsers.
         | 
| 31 31 | 
             
                    #
         | 
| 32 | 
            -
                    # @param [ | 
| 33 | 
            -
                    # | 
| 34 | 
            -
                    #                             Null or empty string value (the default setting) means the content of resulting
         | 
| 35 | 
            -
                    #                             file should be encoded as Base64 and passed as the endpount response value.
         | 
| 36 | 
            -
                    #                             An exception will be thrown if the generated media file is too big to
         | 
| 37 | 
            -
                    #                             fit into the available process memory.
         | 
| 38 | 
            -
                    #                             This option only has an effect if there is screen recording process in progreess
         | 
| 39 | 
            -
                    #                             and +forceRestart+ parameter is not set to +true+.
         | 
| 40 | 
            -
                    # @param [String] user The name of the user for the remote authentication.
         | 
| 41 | 
            -
                    # @param [String] pass The password for the remote authentication.
         | 
| 42 | 
            -
                    # @param [String] method The http multipart upload method name. The 'PUT' one is used by default.
         | 
| 43 | 
            -
                    # @param [Boolean] force_restart Whether to try to catch and upload/return the currently running screen recording
         | 
| 44 | 
            -
                    #                                (+false+, the default setting on server) or ignore the result of it
         | 
| 45 | 
            -
                    #                                and start a new recording immediately (+true+).
         | 
| 46 | 
            -
                    # @param [String] time_limit Recording time. 180 seconds is by default.
         | 
| 32 | 
            +
                    # @param [Boolean] force_restart Whether to stop existing recording process forcefully and start a new recording process.
         | 
| 33 | 
            +
                    # @param [String] time_limit Recording time. 600 seconds is by default.
         | 
| 47 34 | 
             
                    # @param [Number|String] fps The count of frames per second in the resulting video.
         | 
| 48 35 | 
             
                    #                            Increasing fps value also increases the size of the resulting
         | 
| 49 36 | 
             
                    #                            video file and the CPU usage. Defaults to 15.
         | 
| @@ -73,6 +60,7 @@ module Appium | |
| 73 60 | 
             
                    # @param [String] audio_input If provided then the given audio input will be used to record the computer audio
         | 
| 74 61 | 
             
                    #                             along with the desktop video. The list of available devices could be retrieved using
         | 
| 75 62 | 
             
                    #                             +ffmpeg -list_devices true -f dshow -i dummy+ command.
         | 
| 63 | 
            +
                    # @return [String] Base64 encoded content of the recorded media file
         | 
| 76 64 | 
             
                    #
         | 
| 77 65 | 
             
                    # @example
         | 
| 78 66 | 
             
                    #
         | 
| @@ -19,15 +19,11 @@ module Appium | |
| 19 19 | 
             
                    module Screen
         | 
| 20 20 | 
             
                      def self.add_methods
         | 
| 21 21 | 
             
                        ::Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
         | 
| 22 | 
            -
                           | 
| 23 | 
            -
                          def start_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT',
         | 
| 24 | 
            -
                                                     force_restart: nil, time_limit: nil,
         | 
| 22 | 
            +
                          def start_recording_screen(force_restart: nil, time_limit: nil,
         | 
| 25 23 | 
             
                                                     fps: nil, preset: nil, video_filter: nil,
         | 
| 26 24 | 
             
                                                     capture_clicks: nil, capture_cursor: nil, audio_input: nil)
         | 
| 27 | 
            -
                            option =  | 
| 28 | 
            -
             | 
| 29 | 
            -
                            ).upload_option
         | 
| 30 | 
            -
             | 
| 25 | 
            +
                            option = {}
         | 
| 26 | 
            +
                            option[:forceRestart] = force_restart unless force_restart.nil?
         | 
| 31 27 | 
             
                            option[:timeLimit] = time_limit unless time_limit.nil?
         | 
| 32 28 | 
             
                            option[:fps] = fps unless fps.nil?
         | 
| 33 29 | 
             
                            option[:preset] = preset unless preset.nil?
         | 
| @@ -38,7 +34,6 @@ module Appium | |
| 38 34 |  | 
| 39 35 | 
             
                            execute(:start_recording_screen, {}, { options: option })
         | 
| 40 36 | 
             
                          end
         | 
| 41 | 
            -
                          # rubocop:enable Metrics/ParameterLists
         | 
| 42 37 | 
             
                        end
         | 
| 43 38 | 
             
                      end
         | 
| 44 39 | 
             
                    end # module Screen
         | 
    
        data/release_notes.md
    CHANGED
    
    | @@ -1,3 +1,45 @@ | |
| 1 | 
            +
            #### v3.10.0 2020-06-09
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            - [9eff959](https://github.com/appium/ruby_lib_core/commit/9eff959240effde56460c77878a24a20d047f9e9) Release 3.10.0
         | 
| 4 | 
            +
            - [0602e2a](https://github.com/appium/ruby_lib_core/commit/0602e2ab2b332f7db8e39b7da73707a50720fadd) feat: Remove timeout deprecated (#267)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
             | 
| 7 | 
            +
            #### v3.9.0 2020-05-31
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            - [f306188](https://github.com/appium/ruby_lib_core/commit/f306188102222088fbd31b0b9249c6a39ddd074f) Release 3.9.0
         | 
| 10 | 
            +
            - [30c6529](https://github.com/appium/ruby_lib_core/commit/30c65299e4dffb9a2cea8b7a11b27cfcba294707) ci: run with Xcode 11.5 (#265)
         | 
| 11 | 
            +
            - [a10f2d1](https://github.com/appium/ruby_lib_core/commit/a10f2d15ef83e9ce7003b88ec1c0923c922974ea) feat: allow :capabilities as argument (#266)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
             | 
| 14 | 
            +
            #### v3.8.0 2020-05-17
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            - [8986a54](https://github.com/appium/ruby_lib_core/commit/8986a5400d6a3575b7413f15bb61de09af2ec789) Release 3.8.0
         | 
| 17 | 
            +
            - [2379f9a](https://github.com/appium/ruby_lib_core/commit/2379f9a69b43e8c2d2b584ac1e56d3a1aea5e85b) refactor: move idempotency in driver (#264)
         | 
| 18 | 
            +
            - [8103619](https://github.com/appium/ruby_lib_core/commit/8103619313328064df516e7094e2c8a6e1e9719c) fix: x-idempotency-key only for a new session (#263)
         | 
| 19 | 
            +
            - [971f912](https://github.com/appium/ruby_lib_core/commit/971f912a6b4d8e28896d146939c9e5b86dd4b1e0) feat: Add options for start_recording_screen (#261)
         | 
| 20 | 
            +
            - [11f840a](https://github.com/appium/ruby_lib_core/commit/11f840a2945b0376bb3ad762e9b2eefd0aace3b4) ci: add wait
         | 
| 21 | 
            +
            - [4931f4e](https://github.com/appium/ruby_lib_core/commit/4931f4e318e94f9253edd649757f5c774c3404a7) ci: tweak flaky case
         | 
| 22 | 
            +
            - [cb6ef1a](https://github.com/appium/ruby_lib_core/commit/cb6ef1a74dae7200952630076dd58af6bb9500ec) Merge branch 'master' of github.com:appium/ruby_lib_core
         | 
| 23 | 
            +
            - [9117de2](https://github.com/appium/ruby_lib_core/commit/9117de2674f018cfe8e10d9dadc188af846e6be4) ci: relax tests for uia2
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
            #### v3.7.0 2020-04-18
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            - [5ffe630](https://github.com/appium/ruby_lib_core/commit/5ffe630e670943c6f6f60c0e331cdab4685e31c7) Release 3.7.0
         | 
| 29 | 
            +
            - [e561c8d](https://github.com/appium/ruby_lib_core/commit/e561c8db5b00f1132391f8ea79133c295d39a90b) feat: Add chrome devtools endpoints (#260)
         | 
| 30 | 
            +
            - [73cf85f](https://github.com/appium/ruby_lib_core/commit/73cf85fd6ab5bdfb9df7833a713b8d4df3e51a70) test: add w3c send_keys action
         | 
| 31 | 
            +
            - [b1c36fa](https://github.com/appium/ruby_lib_core/commit/b1c36fa538c145326dc50f49ab4d738478e5e0ac) fix typo
         | 
| 32 | 
            +
            - [350ba7b](https://github.com/appium/ruby_lib_core/commit/350ba7bdafd567dabc9bd54ab1476740c6f54a20) feat: Add x idempotency header (#259)
         | 
| 33 | 
            +
            - [94f16d8](https://github.com/appium/ruby_lib_core/commit/94f16d83909a2fb6111d281a00c0b911a00bb23c) ci: bump to Xcode 11.4 and iOS 13.4 (#257)
         | 
| 34 | 
            +
            - [53b7191](https://github.com/appium/ruby_lib_core/commit/53b7191b89e61d11b06628d710a13dac5ca9dfaf) ci: add -accel auto
         | 
| 35 | 
            +
             | 
| 36 | 
            +
             | 
| 37 | 
            +
            #### v3.6.1 2020-03-16
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            - [46a2277](https://github.com/appium/ruby_lib_core/commit/46a2277e792cc583c9978db3ebd548bfee343942) Release 3.6.1
         | 
| 40 | 
            +
            - [2e28b32](https://github.com/appium/ruby_lib_core/commit/2e28b3205e83358e0aaba79d844c30ac7e29917d) fix: Tweak screen option (#256)
         | 
| 41 | 
            +
             | 
| 42 | 
            +
             | 
| 1 43 | 
             
            #### v3.6.0 2020-03-15
         | 
| 2 44 |  | 
| 3 45 | 
             
            - [260d45e](https://github.com/appium/ruby_lib_core/commit/260d45e28a36e99e3dedbe8d41e2703c4d3fbdc8) Release 3.6.0
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: appium_lib_core
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 3. | 
| 4 | 
            +
              version: 3.10.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Kazuaki MATSUO
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020- | 
| 11 | 
            +
            date: 2020-06-09 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: selenium-webdriver
         | 
| @@ -339,7 +339,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 339 339 | 
             
                - !ruby/object:Gem::Version
         | 
| 340 340 | 
             
                  version: '0'
         | 
| 341 341 | 
             
            requirements: []
         | 
| 342 | 
            -
            rubygems_version: 3.0. | 
| 342 | 
            +
            rubygems_version: 3.0.1
         | 
| 343 343 | 
             
            signing_key: 
         | 
| 344 344 | 
             
            specification_version: 4
         | 
| 345 345 | 
             
            summary: Minimal Ruby library for Appium.
         |