appium / ruby_lib

:gem: Ruby library for Appium
http://rubygems.org/gems/appium_lib
216 stars 160 forks source link

Getting a Selenium::WebDriver::Error::InvalidSessionIdError when upgrading rbenv #917

Closed jmelki39 closed 2 years ago

jmelki39 commented 2 years ago

The problem

Briefly describe the issue you are experiencing (or the feature you want to see added to Appium). Tell us what you were trying to do and what happened instead. Remember, this is not a place to ask questions. For that, go to http://discuss.appium.io!

Environment

Details

I have been running my Android mobile automation fine for a couple years using Appium Desktop v1.14.0, Ruby on Rails and Cucumber without updating any versions because I know its fragile and I don't want to spend time fixing everything once I upgrade to newer versions. I ended up running brew upgrade rbenv ruby-build and it upgraded my rbenv and ruby-build and now my automation has been failing. In my trouble shooting, I upgraded Appium to v1.21.0 and continue to get the same error I was seeing in v1.14.0. I am using rbenv 2.6.3 and `rbenv install' support: /usr/local/bin/rbenv-install (ruby-build 20220125)

Link to Appium logs

(https://gist.github.com/jmelki39/77237d559d904a1300061f99e9dedb4d)

Code To Reproduce Issue [ Good To Have ]

I'm not even sure what part of Code to put in here, but I think the issue is with my mobile driver? And this is how I have it setup in the code:

def initialize_mobile_driver
  $driver = nil

  caps = get_capabilities

  $driver = Appium::Driver.new(caps, true)
  Appium.promote_appium_methods(Support::Screens)

  $driver.start_driver
end

def driver_quit
  $driver.driver_quit
end
mykola-mokhnach commented 2 years ago

I don't observe any issues on the server side. The session has been deleted first:

[debug] [W3C (0e9f2455)] Calling AppiumDriver.deleteSession() with args: ["0e9f2455-8aa3-453b-8063-32bb23e269fb"]

and then a command to find a new element is sent to it:

[info] [HTTP] [info] [HTTP] --> POST /wd/hub/session/0e9f2455-8aa3-453b-8063-32bb23e269fb/element

So the exception in the log is expected. Make sure the session management on the client side is working properly

jmelki39 commented 2 years ago

@mykola-mokhnach So I am able to run my first test case successfully, but then get the A session is either terminated or not started (Selenium::WebDriver::Error::InvalidSessionIdError) NoSuchDriverError: A session is either terminated or not started

error once Appium goes to my next test. My 'Before' and 'After' functions worked fine in the past where I initialize the mobile driver in Before and then quit the driver in my After. Why now is this no longer working?

jmelki39 commented 2 years ago

@mykola-mokhnach Another thing to add. As soon as the first test completes successfully, I see this:

'buttons' is already defined. Skipping to override it. 'button' is already defined. Skipping to override it. 'first_button' is already defined. Skipping to override it. 'last_button' is already defined. Skipping to override it. 'button_exact' is already defined. Skipping to override it. 'buttons_exact' is already defined. Skipping to override it. 'complex_find_exact' is already defined. Skipping to override it. 'string_visible_exact' is already defined. Skipping to override it. 'complex_finds_exact' is already defined. Skipping to override it. 'string_visible_contains' is already defined. Skipping to override it. 'complex_find_contains' is already defined. Skipping to override it. 'complex_finds_contains' is already defined. Skipping to override it. 'stop_logs_broadcast' is already defined. Skipping to override it. 'shell' is already defined. Skipping to override it. 'start_logs_broadcast' is already defined. Skipping to override it. 'page' is already defined. Skipping to override it. 'textfield' is already defined. Skipping to override it. 'textfields' is already defined. Skipping to override it. 'first_textfield' is already defined. Skipping to override it. 'last_textfield' is already defined. Skipping to override it. 'textfield_exact' is already defined. Skipping to override it. 'textfields_exact' is already defined. Skipping to override it. 'texts' is already defined. Skipping to override it. 'first_text' is already defined. Skipping to override it. 'last_text' is already defined. Skipping to override it. 'text_exact' is already defined. Skipping to override it. 'texts_exact' is already defined. Skipping to override it. 'id' is already defined. Skipping to override it. 'text' is already defined. Skipping to override it. 'tags' is already defined. Skipping to override it. 'ids' is already defined. Skipping to override it. 'ele_index' is already defined. Skipping to override it. 'find' is already defined. Skipping to override it. 'first_ele' is already defined. Skipping to override it. 'get_android_inspect' is already defined. Skipping to override it. 'last_ele' is already defined. Skipping to override it. 'resource_id' is already defined. Skipping to override it. 'tag' is already defined. Skipping to override it. 'string_visible_contains_xpath' is already defined. Skipping to override it. 'string_visible_exact_xpath' is already defined. Skipping to override it. 'alert_click' is already defined. Skipping to override it. 'alert_accept_text' is already defined. Skipping to override it. 'alert_dismiss_text' is already defined. Skipping to override it. 'alert_accept' is already defined. Skipping to override it. 'alert_dismiss' is already defined. Skipping to override it. 'scroll_uiselector' is already defined. Skipping to override it. 'scroll_to' is already defined. Skipping to override it. 'scroll_to_exact' is already defined. Skipping to override it. 'finds' is already defined. Skipping to override it. 'find_exact' is already defined. Skipping to override it. 'finds_exact' is already defined. Skipping to override it. 'pinch' is already defined. Skipping to override it. 'zoom' is already defined. Skipping to override it. 'swipe' is already defined. Skipping to override it. 'get_log' is already defined. Skipping to override it. 'wait_true' is already defined. Skipping to override it. 'xml_values' is already defined. Skipping to override it. 'xml_keys' is already defined. Skipping to override it. 'resolve_id' is already defined. Skipping to override it. '_print_source' is already defined. Skipping to override it. 'xpaths' is already defined. Skipping to override it. '_no_such_element' is already defined. Skipping to override it. 'wait' is already defined. Skipping to override it. 'back' is already defined. Skipping to override it. 'source' is already defined. Skipping to override it. 'ignore' is already defined. Skipping to override it. 'xpath' is already defined. Skipping to override it. 'get_page_class' is already defined. Skipping to override it. 'get_source' is already defined. Skipping to override it. 'page_class' is already defined. Skipping to override it. 'session_id' is already defined. Skipping to override it. 'px_to_window_rel' is already defined. Skipping to override it. 'lazy_load_strings' is already defined. Skipping to override it. 'get_available_log_types' is already defined. Skipping to override it. 'available_contexts' is already defined. Skipping to override it. 'set_context' is already defined. Skipping to override it. 'current_context' is already defined. Skipping to override it. 'touch_actions' is already defined. Skipping to override it. 'multi_touch' is already defined. Skipping to override it. 'set_immediate_value' is already defined. Skipping to override it. 'replace_value' is already defined. Skipping to override it. 'close_app' is already defined. Skipping to override it. 'background_app' is already defined. Skipping to override it. 'app_strings' is already defined. Skipping to override it. 'device_locked?' is already defined. Skipping to override it. 'device_time' is already defined. Skipping to override it. 'install_app' is already defined. Skipping to override it. 'remove_app' is already defined. Skipping to override it. 'app_installed?' is already defined. Skipping to override it. 'activate_app' is already defined. Skipping to override it. 'terminate_app' is already defined. Skipping to override it. 'app_state' is already defined. Skipping to override it. 'shake' is already defined. Skipping to override it. 'hide_keyboard' is already defined. Skipping to override it. 'press_keycode' is already defined. Skipping to override it. 'long_press_keycode' is already defined. Skipping to override it. 'push_file' is already defined. Skipping to override it. 'pull_file' is already defined. Skipping to override it. 'pull_folder' is already defined. Skipping to override it. 'get_clipboard' is already defined. Skipping to override it. 'stop_and_save_recording_screen' is already defined. Skipping to override it. 'execute_cdp' is already defined. Skipping to override it. 'get_settings' is already defined. Skipping to override it. 'update_settings' is already defined. Skipping to override it. 'stop_recording_screen' is already defined. Skipping to override it. 'system_bars' is already defined. Skipping to override it. 'compare_images' is already defined. Skipping to override it. 'is_keyboard_shown' is already defined. Skipping to override it. 'execute_driver' is already defined. Skipping to override it. 'launch_app' is already defined. Skipping to override it. 'set_clipboard' is already defined. Skipping to override it. 'start_recording_screen' is already defined. Skipping to override it. 'open_notifications' is already defined. Skipping to override it. 'toggle_airplane_mode' is already defined. Skipping to override it. 'start_activity' is already defined. Skipping to override it. 'current_activity' is already defined. Skipping to override it. 'current_package' is already defined. Skipping to override it. 'get_system_bars' is already defined. Skipping to override it. 'get_display_density' is already defined. Skipping to override it. 'toggle_wifi' is already defined. Skipping to override it. 'toggle_data' is already defined. Skipping to override it. 'toggle_location_services' is already defined. Skipping to override it. 'end_coverage' is already defined. Skipping to override it. 'get_performance_data_types' is already defined. Skipping to override it. 'get_performance_data' is already defined. Skipping to override it. 'get_network_connection' is already defined. Skipping to override it. 'set_network_connection' is already defined. Skipping to override it. 'send_sms' is already defined. Skipping to override it. 'gsm_call' is already defined. Skipping to override it. 'gsm_signal' is already defined. Skipping to override it. 'gsm_voice' is already defined. Skipping to override it. 'set_network_speed' is already defined. Skipping to override it. 'set_power_capacity' is already defined. Skipping to override it. 'set_power_ac' is already defined. Skipping to override it. 'finger_print' is already defined. Skipping to override it. 'lock' is already defined. Skipping to override it. 'unlock' is already defined. Skipping to override it. 'ime_activate' is already defined. Skipping to override it. 'ime_available_engines' is already defined. Skipping to override it. 'ime_active_engine' is already defined. Skipping to override it. 'ime_activated' is already defined. Skipping to override it. 'within_context' is already defined. Skipping to override it. 'switch_to_default_context' is already defined. Skipping to override it. 'keyevent' is already defined. Skipping to override it. 'battery_info' is already defined. Skipping to override it. 'match_images_features' is already defined. Skipping to override it. 'save_viewport_screenshot' is already defined. Skipping to override it. 'take_element_screenshot' is already defined. Skipping to override it. 'find_image_occurrence' is already defined. Skipping to override it. 'reset' is already defined. Skipping to override it. 'get_images_similarity' is already defined. Skipping to override it. 'ime_deactivate' is already defined. Skipping to override it. 'automation_name_is_xcuitest?' is already defined. Skipping to override it. 'appium_client_version' is already defined. Skipping to override it. 'restart' is already defined. Skipping to override it. 'automation_name_is_uiautomator2?' is already defined. Skipping to override it. 'set_implicit_wait' is already defined. Skipping to override it. 'device_is_windows?' is already defined. Skipping to override it. 'no_wait' is already defined. Skipping to override it. 'set_wait' is already defined. Skipping to override it. 'exists' is already defined. Skipping to override it. 'manage' is already defined. Skipping to override it. 'navigate' is already defined. Skipping to override it. 'title' is already defined. Skipping to override it. 'execute_async_script' is already defined. Skipping to override it. 'log_event=' is already defined. Skipping to override it. 'global_webdriver_http_sleep=' is already defined. Skipping to override it. 'current_url' is already defined. Skipping to override it. 'caps' is already defined. Skipping to override it. 'custom_url' is already defined. Skipping to override it. 'default_wait' is already defined. Skipping to override it. 'export_session' is already defined. Skipping to override it. 'export_session_path' is already defined. Skipping to override it. 'http_client' is already defined. Skipping to override it. 'find_element' is already defined. Skipping to override it. 'driver' is already defined. Skipping to override it. 'switch_to' is already defined. Skipping to override it. 'remote_status' is already defined. Skipping to override it. 'find_elements' is already defined. Skipping to override it. 'server_url' is already defined. Skipping to override it. 'get' is already defined. Skipping to override it. 'quit_driver' is already defined. Skipping to override it. 'appium_server_version' is already defined. Skipping to override it. 'platform_version' is already defined. Skipping to override it. 'element_screenshot' is already defined. Skipping to override it. 'window_handle' is already defined. Skipping to override it. 'automation_name' is already defined. Skipping to override it. 'window_handles' is already defined. Skipping to override it. 'log_events' is already defined. Skipping to override it. 'log_event' is already defined. Skipping to override it. 'action' is already defined. Skipping to override it. 'x' is already defined. Skipping to override it. 'execute_script' is already defined. Skipping to override it. 'find_element_by_image' is already defined. Skipping to override it. 'find_elements_by_image' is already defined. Skipping to override it. 'global_webdriver_http_sleep' is already defined. Skipping to override it. 'sauce' is already defined. Skipping to override it. 'sauce_username' is already defined. Skipping to override it. 'sauce_access_key' is already defined. Skipping to override it. 'sauce_endpoint' is already defined. Skipping to override it. 'appium_port' is already defined. Skipping to override it. 'appium_device' is already defined. Skipping to override it. 'appium_wait_timeout' is already defined. Skipping to override it. 'appium_wait_interval' is already defined. Skipping to override it. 'appium_server_status' is already defined. Skipping to override it. 'appium_debug' is already defined. Skipping to override it. 'core' is already defined. Skipping to override it. 'window_size' is already defined. Skipping to override it. 'driver_quit' is already defined. Skipping to override it. 'window_rect' is already defined. Skipping to override it. 'start_driver' is already defined. Skipping to override it. 'set_location' is already defined. Skipping to override it. 'driver_attributes' is already defined. Skipping to override it. 'device_is_android?' is already defined. Skipping to override it. 'device_is_ios?' is already defined. Skipping to override it. 'listener' is already defined. Skipping to override it. 'screenshot' is already defined. Skipping to override it. 'automation_name_is_espresso?' is already defined. Skipping to override it.

KazuCocoa commented 2 years ago

The warning is logged when you call promote_appium_methods multiple times to notify redundant define_method call since ruby lib 11.1.0. https://github.com/appium/ruby_lib/blob/5683456f6c6f434d3fa1490a250d23acc3033729/lib/appium_lib/appium.rb#L205-L208

KazuCocoa commented 2 years ago

what version of ruby appium client use before/after your env upgrade?

jmelki39 commented 2 years ago

@KazuCocoa I was using Ruby rbenv 2.6.3 and appium desktop 1.14.0. Now Im on Ruby rbenv 3.1.0 and appium desktop 1.21.0.

Any ideas on my driver issue?

jmelki39 commented 2 years ago

This is what my Before function looks like (it hasn't changed since upgrading):

 def initialize_mobile_driver
  $driver = nil

  caps = get_capabilities

  $driver = Appium::Driver.new(caps, true)
  Appium.promote_appium_methods(Support::Screens)

  $driver.start_driver
end
KazuCocoa commented 2 years ago

I mean the version of https://github.com/appium/ruby_lib, not Ruby version. Usually you manage Ruby's dependencies with Gemfile and Gemfile.lock, I believe.

mykola-mokhnach commented 2 years ago

error once Appium goes to my next test. My 'Before' and 'After' functions worked fine in the past where I initialize the mobile driver in Before and then quit the driver in my After. Why now is this no longer working?

AFAIK a major security issue was fixed which basically was allowing to ignore the session identifier. Now it is being verified, so it is not possible anymore to send session commands if a wrong/expired/deleted session id is provided in the request path.

jmelki39 commented 2 years ago

@mykola-mokhnach Im still confused about what I'm doing wrong. How am I sending a session command that is wrong/expired/deleted? Im stop and restart the drive each time a new test runs. What is recommended to do?

jmelki39 commented 2 years ago

I mean the version of https://github.com/appium/ruby_lib, not Ruby version. Usually you manage Ruby's dependencies with Gemfile and Gemfile.lock, I believe.

I don't see 'ruby_lib' at all listed in my Gemfile.lock

KazuCocoa commented 2 years ago

The package name is appium_lib as its readme. So, https://rubygems.org/gems/appium_lib is. I guess you've upgraded old version to latest? one when you upgraded your Ruby version. Then. I guess your global variable usage got break in a version from the old one to the new one. Then, it needs debug your code and ruby_lib.

In ruby_lib, https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/driver.rb#L203 puts themselves as $driver in Appium::Driver's initializer.

Your reported behavior is probably the previous driver's global variable instance was used after the new one. The new test session did not update the global variable's value from the previous one.

Personally, i'd recommend you to not use global variable as possible to restrict variable's scope.

jmelki39 commented 2 years ago

@KazuCocoa Thank you! So in order to not use the global variable, do I just change $driver = Appium::Driver.new(caps, true) to be 'false'?

`def get_capabilities
  ENV['PLATFORM_NAME'] == 'ANDROID'
    file = "appium_android.txt"

  text_file = File.join(__dir__, "../support/#{file}")
  caps = Appium.load_appium_txt(file: text_file)
  caps[:caps][:deviceName] ||= ENV['DEVICE_NAME']
  caps[:caps][:platformName] ||= ENV['PLATFORM_NAME']
  caps[:caps][:platformVersion] ||= ENV['PLATFORM_VERSION']
  caps[:caps][:app] ||= ENV['APP']
  caps[:caps][:udid] ||= ENV['UDID']

  caps
end

def initialize_mobile_driver
  $driver = nil

  caps = get_capabilities

  $driver = Appium::Driver.new(caps, true)
  Appium.promote_appium_methods(Support::Screens)

  $driver.start_driver
end`
KazuCocoa commented 2 years ago

do I just change $driver = Appium::Driver.new(caps, true) to be 'false'?

Yes. Then, the appium_ruby lib no longer modifies $driver internally.

jmelki39 commented 2 years ago

do I just change $driver = Appium::Driver.new(caps, true) to be 'false'?

Yes. Then, the appium_ruby lib no longer modifies $driver internally.

I tried that but I'm still getting the same error...

KazuCocoa commented 2 years ago

Then, $driver in your code might affect your test case. Did you confirm what version of appium_lib did you used in your env was Ruby 2.6, and what version in Ruby 3.1 env?

Probably you can compare appium_lib 10.6.0 with Ruby 2.6, and appium_lib 11.0 with Ruby 2.6 etc so that the issue was appium_lib or your other dependencies/Ruby versions.

jmelki39 commented 2 years ago

Then, $driver in your code might affect your test case. Did you confirm what version of appium_lib did you used in your env was Ruby 2.6, and what version in Ruby 3.1 env?

Probably you can compare appium_lib 10.6.0 with Ruby 2.6, and appium_lib 11.0 with Ruby 2.6 etc so that the issue was appium_lib or your other dependencies/Ruby versions.

I believe it was version 10.4.0 for both Ruby 2.6 and Ruby 3.1. Should I be updated to version 11 or 12 though? I try to run gem update appium_lib but it says is already up to date

KazuCocoa commented 2 years ago

I believe it was version 10.4.0 for both Ruby 2.6 and Ruby 3.1

Then, perhaps it is something Ruby 3.1 env's issue to handle global variable. e.g. the usage has changed or something.

mykola-mokhnach commented 2 years ago

@KazuCocoa Shall we move the issue elsewhere to ruby client tracker? It has nothing to do with the server functionality

KazuCocoa commented 2 years ago

yup, let me move

waynemd commented 2 years ago

@KazuCocoa , i got same issue after I upgrade to appium_lib 12 version (https://github.com/appium/ruby_lib/issues/917#issuecomment-1041757326). I use ruby 2.7.5 version and it works on the old appium_lib 10 but not on appium_lib 12. what's the solution for it?

KazuCocoa commented 2 years ago

Could you share the appium log and ruby log possibly?

I don't know if your case is the global variable thing, but one possible diff between 10 and 12 that could be related to the global driver is the below default value change. https://github.com/appium/ruby_lib/compare/v10.6.0...v12.0.0#diff-e79205e5a6c4b0bcaf417522b013e796ddb7049c0221f716ede29dce3b65e62dR154

KazuCocoa commented 2 years ago

Possibly this is related to Cucumber integration stuff. I don't know the integration, but if it cannot give the global driver argument properly, global_driver as an option to Appium::Driver.new will help. e.g.:

opts = {
         caps: {
           platformName: :ios,
           app: '/path/to/MyiOS.app'
         },
         appium_lib: {
           wait_timeout: 30
         },
         global_driver: true
       }
appium_driver = Appium::Driver.new(opts)
appium_driver.start_driver

https://github.com/appium/appium_capybara/blob/0d30dde8a8548f7c933270958b5cf3ca5978ba6a/example/spec/capybara_init.rb#L12 is when I added global_driver in the capybara example.

KazuCocoa commented 2 years ago

Probably I could reproduce. v11 had no issue, so it is in v12 change stuff. Potentially selenium v4 update also affected somewhere, but i haven't figure it out yet.

KazuCocoa commented 2 years ago

this was because of v11.2's Ruby 3 update. https://github.com/appium/ruby_lib/pull/893/files#diff-8ea275ac8a0a8f75d9ffea422eba089783fc7634ab4ef51095dacdef34cf7dc8R207-R210

So, this was not global variables. This was promote_appium_methods's issue. Then, the previous session's session-id remained in the next session.

This was to avoid redundant definition purpose, but probably unexpected state remained then. So, delete it once -> re-define it may be better.

KazuCocoa commented 2 years ago

Could you try the branch out by adding gem 'appium_lib', git: 'https://github.com/appium/ruby_lib.git', branch: 'remove' as Gemfile?

waynemd commented 2 years ago

@KazuCocoa , the branch works. Thanks!

KazuCocoa commented 2 years ago

12.0.1 has the fix. Please try it out

waynemd commented 2 years ago

@KazuCocoa working for me. thanks for the quick fix and quick release!