appium_lib_core 5.7.0 → 5.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fdc105db151bc415072c5c693ec951a14ea681762f686be52941b89d48eb879c
4
- data.tar.gz: 74ae58624c62216572e321b22386b530f3271ffeeba15b9e25764b9ffda5328d
3
+ metadata.gz: 06c7b0bb078ece1a833874436e4611cb407cc762d73dd2fbcb27e69ace076e14
4
+ data.tar.gz: ab4e2733c06ed9866368e983c4e2a28510a4125eff5614e404c3e83f1eaceae9
5
5
  SHA512:
6
- metadata.gz: 0a52ad3c06dc494049be9c72cf7e74fea74ad005b4c45bc87ae308e3b27e180f0488c0a9e967e16992031d5282f637bba35b5aa80235ece79d1307e9e05ca120
7
- data.tar.gz: 160ec09d1c7f1205ade5e17fab276a3e68f10250b7c3ff84a5984b9fd875a7d74238fc5cc7bb2c6c960ccf581993b642718fba6b7f8731df2e74e1d676c0f2ae
6
+ metadata.gz: fd894aaad52613559c842c0a42ff6d6bbfc9b871ea5f3bf02a302f7ae53e9b7cb6397bea363f9108ac9bbe601f1f1cacb5fa38ee4371eebaf875d2e64b756cf4
7
+ data.tar.gz: '097f706be4f0403e6397bdb941f1f63ced8c6cfae8a7f68af401ffcd0fa2e75d81051b37d1f421c9d60051c85f125c6662edb8461f8fcbc7afcaa6a89ba69142'
data/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@ Read `release_notes.md` for commit level details.
10
10
 
11
11
  ### Deprecations
12
12
 
13
+ ## [5.8.0] - 2022-12-11
14
+
15
+ ### Enhancements
16
+ - Add `::Appium::Core::Driver#attach_to` to generate a driver instance which has the given session id.
17
+ - The primary usage is for debugging to attach to an existing session.
18
+
13
19
  ## [5.7.0] - 2022-12-02
14
20
 
15
21
  ### Enhancements
data/README.md CHANGED
@@ -104,7 +104,7 @@ $ IGNORE_VERSION_SKIP=true CI=true bundle exec rake test:func:android
104
104
 
105
105
  opts = {
106
106
  capabilities: { # Append capabilities
107
- platformName: :ios,
107
+ platformName: 'ios',
108
108
  platformVersion: '11.0',
109
109
  deviceName: 'iPhone Simulator',
110
110
  automationName: 'XCUITest',
@@ -133,6 +133,15 @@ $ IGNORE_VERSION_SKIP=true CI=true bundle exec rake test:func:android
133
133
 
134
134
  More examples are in [test/functional](test/functional)
135
135
 
136
+ As of version 5.8.0, the client can attach to an existing session. The main purpose is for debugging.
137
+
138
+ ```ruby
139
+ # @driver is the driver instance of an existing session
140
+ attached_driver = ::Appium::Core::Driver.attach_to @driver.session_id, url: 'http://127.0.0.1:4723/wd/hub', automation_name: 'XCUITest', platform_name: 'ios'
141
+ assert attached_driver.session_id == @driver.session_id
142
+ attached_driver.page_source
143
+ ```
144
+
136
145
  ### Capabilities
137
146
 
138
147
  Read [Appium/Core/Driver](https://www.rubydoc.info/github/appium/ruby_lib_core/Appium/Core/Driver) to catch up with available capabilities.
@@ -43,13 +43,39 @@ module Appium
43
43
 
44
44
  def browser
45
45
  @browser ||= begin
46
- name = @capabilities.browser_name
46
+ name = @capabilities&.browser_name
47
47
  name ? name.tr(' ', '_').downcase.to_sym : 'unknown'
48
48
  rescue KeyError
49
49
  APPIUM_NATIVE_BROWSER_NAME
50
50
  end
51
51
  end
52
52
 
53
+ # Appium only.
54
+ # Attach to an existing session.
55
+ #
56
+ # @param [String] The session id to attach to.
57
+ # @param [String] platform_name The platform name to keep in the dummy capabilities
58
+ # @param [String] platform_name The automation name to keep in the dummy capabilities
59
+ # @return [::Appium::Core::Base::Capabilities]
60
+ #
61
+ # @example
62
+ #
63
+ # new_driver = ::Appium::Core::Driver.attach_to(
64
+ # driver.session_id,
65
+ # url: 'http://127.0.0.1:4723/wd/hub', automation_name: 'UiAutomator2', platform_name: 'Android'
66
+ # )
67
+ #
68
+ def attach_to(session_id, platform_name, automation_name)
69
+ @available_commands = ::Appium::Core::Commands::COMMANDS.dup
70
+ @session_id = session_id
71
+
72
+ # generate a dummy capabilities instance which only has the given platformName and automationName
73
+ @capabilities = ::Appium::Core::Base::Capabilities.new(
74
+ 'platformName' => platform_name,
75
+ 'automationName' => automation_name
76
+ )
77
+ end
78
+
53
79
  # Override
54
80
  # Creates session handling.
55
81
  #
@@ -51,10 +51,6 @@ module Appium
51
51
  @wait_timeout = opts.delete(:wait_timeout)
52
52
  @wait_interval = opts.delete(:wait_interval)
53
53
 
54
- # For logging.
55
- # TODO: Remove when appium core no longer uses this in this bridge.
56
- @automation_name = opts.delete(:automation_name)
57
-
58
54
  super
59
55
  end
60
56
 
@@ -63,13 +59,26 @@ module Appium
63
59
  # @return [::Appium::Core::Base::Bridge]
64
60
  #
65
61
  def create_bridge(**opts)
62
+ # for a new session request
66
63
  capabilities = opts.delete(:capabilities)
67
64
  bridge_opts = { http_client: opts.delete(:http_client), url: opts.delete(:url) }
65
+
66
+ # for attaching to an existing session
67
+ session_id = opts.delete(:existing_session_id)
68
+ automation_name = opts.delete(:automation_name)
69
+ platform_name = opts.delete(:platform_name)
70
+
68
71
  raise ::Appium::Core::Error::ArgumentError, "Unable to create a driver with parameters: #{opts}" unless opts.empty?
69
72
 
70
73
  bridge = ::Appium::Core::Base::Bridge.new(**bridge_opts)
71
74
 
72
- bridge.create_session(capabilities)
75
+ if session_id.nil?
76
+ bridge.create_session(capabilities)
77
+ else
78
+ # attach to the existing session id
79
+ bridge.attach_to(session_id, platform_name, automation_name)
80
+ end
81
+
73
82
  bridge
74
83
  end
75
84
 
@@ -566,12 +575,6 @@ module Appium
566
575
  # @driver.launch_app
567
576
  #
568
577
  def launch_app
569
- # TODO: Define only in Windows module when ruby_lib_core removes this method
570
- if @automation_name != :windows
571
- ::Appium::Logger.warn(
572
- '[DEPRECATION] launch_app is deprecated. Please use activate_app instead.'
573
- )
574
- end
575
578
  @bridge.launch_app
576
579
  end
577
580
 
@@ -583,12 +586,6 @@ module Appium
583
586
  # @driver.close_app
584
587
  #
585
588
  def close_app
586
- # TODO: Define only in Windows module when ruby_lib_core removes this method
587
- if @automation_name != :windows
588
- ::Appium::Logger.warn(
589
- '[DEPRECATION] close_app is deprecated. Please use terminate_app instead.'
590
- )
591
- end
592
589
  @bridge.close_app
593
590
  end
594
591
 
@@ -18,10 +18,16 @@ module Appium
18
18
  module Device
19
19
  module AppManagement
20
20
  def launch_app
21
+ ::Appium::Logger.warn(
22
+ '[DEPRECATION] launch_app is deprecated. Please use activate_app instead.'
23
+ )
21
24
  execute :launch_app
22
25
  end
23
26
 
24
27
  def close_app
28
+ ::Appium::Logger.warn(
29
+ '[DEPRECATION] close_app is deprecated. Please use terminate_app instead.'
30
+ )
25
31
  execute :close_app
26
32
  end
27
33
 
@@ -275,7 +275,40 @@ module Appium
275
275
  # @core.start_driver # start driver with 'url'. Connect to 'http://custom-host:8080/wd/hub.com'
276
276
  #
277
277
  def self.for(opts = {})
278
- new(opts)
278
+ new.setup_for_new_session(opts)
279
+ end
280
+
281
+ # Attach to an existing session. The main usage of this method is to attach to
282
+ # an existing session for debugging. The generated driver instance has the capabilities which
283
+ # has the given automationName and platformName only since the W3C WebDriver spec does not provide
284
+ # an endpoint to get running session's capabilities.
285
+ #
286
+ #
287
+ # @param [String] The session id to attach to.
288
+ # @param [String] url The WebDriver URL to attach to with the session_id.
289
+ # @param [String] automation_name The platform name to keep in the dummy capabilities
290
+ # @param [String] platform_name The automation name to keep in the dummy capabilities
291
+ # @return [Selenium::WebDriver] A new driver instance with the given session id.
292
+ #
293
+ # @example
294
+ #
295
+ # new_driver = ::Appium::Core::Driver.attach_to(
296
+ # driver.session_id, # The 'driver' has an existing session id
297
+ # url: 'http://127.0.0.1:4723/wd/hub', automation_name: 'UiAutomator2', platform_name: 'Android'
298
+ # )
299
+ # new_driver.page_source # for example
300
+ #
301
+ def self.attach_to(
302
+ session_id, url: nil, automation_name: nil, platform_name: nil,
303
+ http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 }
304
+ )
305
+ new.attach_to(
306
+ session_id,
307
+ automation_name: automation_name,
308
+ platform_name: platform_name,
309
+ url: url,
310
+ http_client_ops: http_client_ops
311
+ )
279
312
  end
280
313
 
281
314
  private
@@ -286,12 +319,18 @@ module Appium
286
319
  @delegate_target
287
320
  end
288
321
 
289
- public
290
-
291
322
  # @private
292
- def initialize(opts = {})
323
+ def initialize
293
324
  @delegate_target = self # for testing purpose
294
325
  @automation_name = nil # initialise before 'set_automation_name'
326
+ end
327
+
328
+ public
329
+
330
+ # @private
331
+ # Set up for a neww session
332
+ def setup_for_new_session(opts = {})
333
+ @custom_url = opts.delete :url # to set the custom url as :url
295
334
 
296
335
  # TODO: Remove when we implement Options
297
336
  # The symbolize_keys is to keep compatiility for the legacy code, which allows capabilities to give 'string' as the key.
@@ -299,7 +338,6 @@ module Appium
299
338
  # FIXME: First, please try to remove `nested: true` to `nested: false`.
300
339
  opts = Appium.symbolize_keys(opts, nested: true)
301
340
 
302
- @custom_url = opts.delete :url
303
341
  @caps = get_caps(opts)
304
342
 
305
343
  set_appium_lib_specific_values(get_appium_lib_opts(opts))
@@ -308,8 +346,7 @@ module Appium
308
346
  set_automation_name
309
347
 
310
348
  extend_for(device: @device, automation_name: @automation_name)
311
-
312
- self # rubocop:disable Lint/Void
349
+ self
313
350
  end
314
351
 
315
352
  # Creates a new global driver and quits the old one if it exists.
@@ -320,7 +357,7 @@ module Appium
320
357
  # @option http_client_ops [Hash] :http_client Custom HTTP Client
321
358
  # @option http_client_ops [Hash] :open_timeout Custom open timeout for http client.
322
359
  # @option http_client_ops [Hash] :read_timeout Custom read timeout for http client.
323
- # @return [Selenium::WebDriver] the new global driver
360
+ # @return [Selenium::WebDriver] A new driver instance
324
361
  #
325
362
  # @example
326
363
  #
@@ -377,8 +414,7 @@ module Appium
377
414
  capabilities: @caps, # ::Appium::Core::Base::Capabilities
378
415
  url: @custom_url,
379
416
  wait_timeout: @wait_timeout,
380
- wait_interval: @wait_interval,
381
- automation_name: @automation_name)
417
+ wait_interval: @wait_interval)
382
418
 
383
419
  if @direct_connect
384
420
  d_c = DirectConnections.new(@driver.capabilities)
@@ -396,6 +432,8 @@ module Appium
396
432
  @http_client.additional_headers.delete Appium::Core::Base::Http::RequestHeaders::KEYS[:idempotency]
397
433
  end
398
434
 
435
+ # TODO: this method can be removed after releasing Appium 2.0, and after a while
436
+ # since Appium 2.0 reuqires 'automationName'. This method won't help anymore then.
399
437
  # If "automationName" is set only server side, this method set "automationName" attribute into @automation_name.
400
438
  # Since @automation_name is set only client side before start_driver is called.
401
439
  set_automation_name_if_nil
@@ -405,7 +443,47 @@ module Appium
405
443
  @driver
406
444
  end
407
445
 
408
- private
446
+ # @privvate
447
+ # Attach to an existing session
448
+ def attach_to(session_id, url: nil, automation_name: nil, platform_name: nil,
449
+ http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })
450
+
451
+ raise ::Appium::Core::Error::ArgumentError, 'The :url must not be nil' if url.nil?
452
+ raise ::Appium::Core::Error::ArgumentError, 'The :automation_name must not be nil' if automation_name.nil?
453
+ raise ::Appium::Core::Error::ArgumentError, 'The :platform_name must not be nil' if platform_name.nil?
454
+
455
+ @custom_url = url
456
+
457
+ # use lowercase internally
458
+ @automation_name = convert_downcase(automation_name)
459
+ @device = convert_downcase(platform_name)
460
+
461
+ extend_for(device: @device, automation_name: @automation_name)
462
+
463
+ @http_client = get_http_client http_client: http_client_ops.delete(:http_client),
464
+ open_timeout: http_client_ops.delete(:open_timeout),
465
+ read_timeout: http_client_ops.delete(:read_timeout)
466
+
467
+ # Note that 'enable_idempotency_header' works only a new session reqeust. The attach_to method skips
468
+ # the new session request, this it does not needed.
469
+
470
+ begin
471
+ # included https://github.com/SeleniumHQ/selenium/blob/43f8b3f66e7e01124eff6a5805269ee441f65707/rb/lib/selenium/webdriver/remote/driver.rb#L29
472
+ @driver = ::Appium::Core::Base::Driver.new(http_client: @http_client,
473
+ url: @custom_url,
474
+ listener: @listener,
475
+ existing_session_id: session_id,
476
+ automation_name: automation_name,
477
+ platform_name: platform_name)
478
+
479
+ # export session
480
+ write_session_id(@driver.session_id, @export_session_path) if @export_session
481
+ rescue Errno::ECONNREFUSED
482
+ raise "ERROR: Unable to connect to Appium. Is the server running on #{@custom_url}?"
483
+ end
484
+
485
+ @driver
486
+ end
409
487
 
410
488
  def get_http_client(http_client: nil, open_timeout: nil, read_timeout: nil)
411
489
  client = http_client || Appium::Core::Base::Http::Default.new
@@ -431,8 +509,6 @@ module Appium
431
509
  {}
432
510
  end
433
511
 
434
- public
435
-
436
512
  # Quits the driver
437
513
  # @return [void]
438
514
  #
@@ -626,7 +702,7 @@ module Appium
626
702
  @device = @caps[:platformName] || @caps['platformName']
627
703
  return @device unless @device
628
704
 
629
- @device = @device.is_a?(Symbol) ? @device.downcase : @device.downcase.strip.intern
705
+ @device = convert_downcase @device
630
706
  end
631
707
 
632
708
  # @private
@@ -634,9 +710,12 @@ module Appium
634
710
  # TODO: check if the Appium.symbolize_keys(opts, nested: false) enoug with this
635
711
  candidate = @caps[:automationName] || @caps['automationName']
636
712
  @automation_name = candidate if candidate
637
- @automation_name = if @automation_name
638
- @automation_name.is_a?(Symbol) ? @automation_name.downcase : @automation_name.downcase.strip.intern
639
- end
713
+ @automation_name = convert_downcase @automation_name if @automation_name
714
+ end
715
+
716
+ # @private
717
+ def convert_downcase(value)
718
+ value.is_a?(Symbol) ? value.downcase : value.downcase.strip.intern
640
719
  end
641
720
 
642
721
  # @private
@@ -650,6 +729,10 @@ module Appium
650
729
 
651
730
  # @private
652
731
  def write_session_id(session_id, export_path = '/tmp/appium_lib_session')
732
+ ::Appium::Logger.warn(
733
+ '[DEPRECATION] export_session option will be removed. ' \
734
+ 'Please save the session id by yourself with #session_id method like @driver.session_id.'
735
+ )
653
736
  export_path = export_path.tr('/', '\\') if ::Appium::Core::Base.platform.windows?
654
737
  File.write(export_path, session_id)
655
738
  rescue IOError => e
@@ -14,7 +14,7 @@
14
14
 
15
15
  module Appium
16
16
  module Core
17
- VERSION = '5.7.0' unless defined? ::Appium::Core::VERSION
18
- DATE = '2022-12-02' unless defined? ::Appium::Core::DATE
17
+ VERSION = '5.8.0' unless defined? ::Appium::Core::VERSION
18
+ DATE = '2022-12-11' unless defined? ::Appium::Core::DATE
19
19
  end
20
20
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Appium
16
+ module Core
17
+ module Windows
18
+ module Device
19
+ module AppManagement
20
+ # override
21
+ def self.add_methods
22
+ ::Appium::Core::Device.add_endpoint_method(:launch_app) do
23
+ def launch_app
24
+ execute :launch_app
25
+ end
26
+ end
27
+
28
+ ::Appium::Core::Device.add_endpoint_method(:close_app) do
29
+ def close_app
30
+ execute :close_app
31
+ end
32
+ end
33
+ end
34
+ end # module AppManagement
35
+ end # module Device
36
+ end # module Windows
37
+ end # module Core
38
+ end # module Appium
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  require_relative 'device/screen'
16
+ require_relative 'device/app_management'
16
17
 
17
18
  module Appium
18
19
  module Core
@@ -78,6 +79,7 @@ module Appium
78
79
  class << self
79
80
  def extended(_mod)
80
81
  Screen.add_methods
82
+ AppManagement.add_methods
81
83
  end
82
84
  end # class << self
83
85
  end # module Device
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: 5.7.0
4
+ version: 5.8.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: 2022-12-03 00:00:00.000000000 Z
11
+ date: 2022-12-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: selenium-webdriver
@@ -267,6 +267,7 @@ files:
267
267
  - lib/appium_lib_core/windows.rb
268
268
  - lib/appium_lib_core/windows/bridge.rb
269
269
  - lib/appium_lib_core/windows/device.rb
270
+ - lib/appium_lib_core/windows/device/app_management.rb
270
271
  - lib/appium_lib_core/windows/device/screen.rb
271
272
  homepage: https://github.com/appium/ruby_lib_core/
272
273
  licenses: