Best Selenium code snippet using Selenium.WebDriver.selectable
driver.rb
Source:driver.rb  
1# frozen_string_literal: true2require 'uri'3require 'English'4class Capybara::Selenium::Driver < Capybara::Driver::Base5  DEFAULT_OPTIONS = {6    browser: :firefox,7    clear_local_storage: false,8    clear_session_storage: false9  }.freeze10  SPECIAL_OPTIONS = %i[browser clear_local_storage clear_session_storage].freeze11  attr_reader :app, :options12  def self.load_selenium13    require 'selenium-webdriver'14    warn "Warning: You're using an unsupported version of selenium-webdriver, please upgrade." if Gem.loaded_specs['selenium-webdriver'].version < Gem::Version.new('3.5.0')15  rescue LoadError => e16    raise e if e.message !~ /selenium-webdriver/17    raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."18  end19  def browser20    unless @browser21      # if firefox?22      #   options[:desired_capabilities] ||= {}23      #   options[:desired_capabilities][:unexpectedAlertBehaviour] = "ignore"24      # end25      @processed_options = options.reject { |key, _val| SPECIAL_OPTIONS.include?(key) }26      @browser = Selenium::WebDriver.for(options[:browser], @processed_options)27      extend ChromeDriver if chrome?28      extend MarionetteDriver if marionette?29      main = Process.pid30      at_exit do31        # Store the exit status of the test run since it goes away after calling the at_exit proc...32        @exit_status = $ERROR_INFO.status if $ERROR_INFO.is_a?(SystemExit)33        quit if Process.pid == main34        exit @exit_status if @exit_status # Force exit with stored status35      end36    end37    @browser38  end39  def initialize(app, **options)40    self.class.load_selenium41    @session = nil42    @app = app43    @browser = nil44    @exit_status = nil45    @frame_handles = {}46    @options = DEFAULT_OPTIONS.merge(options)47    @node_class = ::Capybara::Selenium::Node48  end49  def visit(path)50    browser.navigate.to(path)51  end52  def refresh53    browser.navigate.refresh54  end55  def go_back56    browser.navigate.back57  end58  def go_forward59    browser.navigate.forward60  end61  def html62    browser.page_source63  end64  def title65    browser.title66  end67  def current_url68    browser.current_url69  end70  def find_xpath(selector)71    browser.find_elements(:xpath, selector).map(&method(:build_node))72  end73  def find_css(selector)74    browser.find_elements(:css, selector).map(&method(:build_node))75  end76  def wait?; true; end77  def needs_server?; true; end78  def execute_script(script, *args)79    browser.execute_script(script, *native_args(args))80  end81  def evaluate_script(script, *args)82    result = execute_script("return #{script}", *args)83    unwrap_script_result(result)84  end85  def evaluate_async_script(script, *args)86    browser.manage.timeouts.script_timeout = Capybara.default_max_wait_time87    result = browser.execute_async_script(script, *native_args(args))88    unwrap_script_result(result)89  end90  def save_screenshot(path, **_options)91    browser.save_screenshot(path)92  end93  def reset!94    # Use instance variable directly so we avoid starting the browser just to reset the session95    return unless @browser96    navigated = false97    timer = Capybara::Helpers.timer(expire_in: 10)98    begin99      unless navigated100        # Only trigger a navigation if we haven't done it already, otherwise it101        # can trigger an endless series of unload modals102        begin103          @browser.manage.delete_all_cookies104          clear_storage105        # rescue Selenium::WebDriver::Error::NoSuchAlertError106        #   # Handle a bug in Firefox/Geckodriver where it thinks it needs an alert modal to exist107        #   # for no good reason108        #   retry109        rescue Selenium::WebDriver::Error::UnhandledError # rubocop:disable Lint/HandleExceptions110          # delete_all_cookies fails when we've previously gone111          # to about:blank, so we rescue this error and do nothing112          # instead.113        end114        @browser.navigate.to('about:blank')115      end116      navigated = true117      # Ensure the page is empty and trigger an UnhandledAlertError for any modals that appear during unload118      until find_xpath('/html/body/*').empty?119        raise Capybara::ExpectationNotMet, 'Timed out waiting for Selenium session reset' if timer.expired?120        sleep 0.05121      end122    rescue Selenium::WebDriver::Error::UnhandledAlertError, Selenium::WebDriver::Error::UnexpectedAlertOpenError123      # This error is thrown if an unhandled alert is on the page124      # Firefox appears to automatically dismiss this alert, chrome does not125      # We'll try to accept it126      begin127        @browser.switch_to.alert.accept128        sleep 0.25 # allow time for the modal to be handled129      rescue modal_error130        # The alert is now gone131        if current_url != 'about:blank'132          begin133            # If navigation has not occurred attempt again and accept alert134            # since FF may have dismissed the alert at first attempt135            @browser.navigate.to('about:blank')136            sleep 0.1 # slight wait for alert137            @browser.switch_to.alert.accept138          rescue modal_error # rubocop:disable Metrics/BlockNesting, Lint/HandleExceptions139            # alert now gone, should mean navigation happened140          end141        end142      end143      # try cleaning up the browser again144      retry145    end146  end147  def switch_to_frame(frame)148    case frame149    when :top150      @frame_handles[browser.window_handle] = []151      browser.switch_to.default_content152    when :parent153      # would love to use browser.switch_to.parent_frame here154      # but it has an issue if the current frame is removed from within it155      @frame_handles[browser.window_handle].pop156      browser.switch_to.default_content157      @frame_handles[browser.window_handle].each { |fh| browser.switch_to.frame(fh) }158    else159      @frame_handles[browser.window_handle] ||= []160      @frame_handles[browser.window_handle] << frame.native161      browser.switch_to.frame(frame.native)162    end163  end164  def current_window_handle165    browser.window_handle166  end167  def window_size(handle)168    within_given_window(handle) do169      size = browser.manage.window.size170      [size.width, size.height]171    end172  end173  def resize_window_to(handle, width, height)174    within_given_window(handle) do175      browser.manage.window.resize_to(width, height)176    end177  end178  def maximize_window(handle)179    within_given_window(handle) do180      browser.manage.window.maximize181    end182    sleep 0.1 # work around for https://code.google.com/p/selenium/issues/detail?id=7405183  end184  def fullscreen_window(handle)185    within_given_window(handle) do186      browser.manage.window.full_screen187    end188  end189  def close_window(handle)190    raise ArgumentError, 'Not allowed to close the primary window' if handle == window_handles.first191    within_given_window(handle) do192      browser.close193    end194  end195  def window_handles196    browser.window_handles197  end198  def open_new_window199    browser.execute_script('window.open();')200  end201  def switch_to_window(handle)202    browser.switch_to.window handle203  end204  def accept_modal(_type, **options)205    yield if block_given?206    modal = find_modal(options)207    modal.send_keys options[:with] if options[:with]208    message = modal.text209    modal.accept210    message211  end212  def dismiss_modal(_type, **options)213    yield if block_given?214    modal = find_modal(options)215    message = modal.text216    modal.dismiss217    message218  end219  def quit220    @browser&.quit221  rescue Selenium::WebDriver::Error::SessionNotCreatedError, Errno::ECONNREFUSED # rubocop:disable Lint/HandleExceptions222    # Browser must have already gone223  rescue Selenium::WebDriver::Error::UnknownError => e224    unless silenced_unknown_error_message?(e.message) # Most likely already gone225      # probably already gone but not sure - so warn226      warn "Ignoring Selenium UnknownError during driver quit: #{e.message}"227    end228  ensure229    @browser = nil230  end231  def invalid_element_errors232    [233      ::Selenium::WebDriver::Error::StaleElementReferenceError,234      ::Selenium::WebDriver::Error::UnhandledError,235      ::Selenium::WebDriver::Error::ElementNotVisibleError,236      ::Selenium::WebDriver::Error::InvalidSelectorError, # Work around a race condition that can occur with chromedriver and #go_back/#go_forward237      ::Selenium::WebDriver::Error::ElementNotInteractableError,238      ::Selenium::WebDriver::Error::ElementClickInterceptedError,239      ::Selenium::WebDriver::Error::InvalidElementStateError,240      ::Selenium::WebDriver::Error::ElementNotSelectableError,241      ::Selenium::WebDriver::Error::ElementNotSelectableError,242      ::Selenium::WebDriver::Error::NoSuchElementError, # IE243      ::Selenium::WebDriver::Error::InvalidArgumentError # IE244    ]245  end246  def no_such_window_error247    Selenium::WebDriver::Error::NoSuchWindowError248  end249private250  def w3c?251    browser && browser.capabilities.is_a?(Selenium::WebDriver::Remote::W3C::Capabilities)252  end253  def marionette?254    firefox? && w3c?255  end256  def firefox?257    browser_name == :firefox258  end259  def chrome?260    browser_name == :chrome261  end262  def edge?263    browser_name == :edge264  end265  def ie?266    %i[internet_explorer ie].include?(browser_name)267  end268  def browser_name269    browser.browser270  end271  def native_args(args)272    args.map { |arg| arg.is_a?(Capybara::Selenium::Node) ? arg.native : arg }273  end274  def clear_storage275    if options[:clear_session_storage]276      if @browser.respond_to? :session_storage277        @browser.session_storage.clear278      else279        warn 'sessionStorage clear requested but is not available for this driver'280      end281    end282    if options[:clear_local_storage] # rubocop:disable Style/GuardClause283      if @browser.respond_to? :local_storage284        @browser.local_storage.clear285      else286        warn 'localStorage clear requested but is not available for this driver'287      end288    end289  end290  def modal_error291    Selenium::WebDriver::Error::NoSuchAlertError292  end293  def within_given_window(handle)294    original_handle = current_window_handle295    if handle == original_handle296      yield297    else298      switch_to_window(handle)299      result = yield300      switch_to_window(original_handle)301      result302    end303  end304  def find_modal(text: nil, **options)305    # Selenium has its own built in wait (2 seconds)for a modal to show up, so this wait is really the minimum time306    # Actual wait time may be longer than specified307    wait = Selenium::WebDriver::Wait.new(308      timeout: options.fetch(:wait, session_options.default_max_wait_time) || 0,309      ignore: modal_error310    )311    begin312      wait.until do313        alert = @browser.switch_to.alert314        regexp = text.is_a?(Regexp) ? text : Regexp.escape(text.to_s)315        alert.text.match(regexp) ? alert : nil316      end317    rescue Selenium::WebDriver::Error::TimeOutError318      raise Capybara::ModalNotFound, "Unable to find modal dialog#{" with #{text}" if text}"319    end320  end321  def silenced_unknown_error_message?(msg)322    silenced_unknown_error_messages.any? { |r| msg =~ r }323  end324  def silenced_unknown_error_messages325    [/Error communicating with the remote browser/]326  end327  def unwrap_script_result(arg)328    case arg329    when Array330      arg.map { |e| unwrap_script_result(e) }331    when Hash332      arg.each { |k, v| arg[k] = unwrap_script_result(v) }333    when Selenium::WebDriver::Element334      build_node(arg)335    else336      arg337    end338  end339  def build_node(native_node)340    ::Capybara::Selenium::Node.new(self, native_node)341  end342end343require 'capybara/selenium/driver_specializations/chrome_driver'344require 'capybara/selenium/driver_specializations/marionette_driver'...selectable
Using AI Code Generation
1  before(:each) do2  after(:each) do3    @driver.get(@base_url + "/")4    @driver.find_element(:id, "gbqfq").clear5    @driver.find_element(:id, "gbqfq").send_keys "selenium webdriver"6    Selenium::WebDriver::Support::Select.new(@driver.find_element(:id, "gbqfsa")).select_by(:text, "Web")7    @driver.find_element(:id, "gbqfb").click8    @driver.find_element(:link, "Selenium - Web Browser Automation").click9    expect(@driver.find_element(:tag_name => "body").text).to match(/Selenium automates browsers/)selectable
Using AI Code Generation
1element = driver.find_element(:name, 'q')2wait.until { driver.title.downcase.start_with? "selenium webdriver" }3all_options = driver.find_element(:tag_name, "select").find_elements(:tag_name, "option")4select = Selenium::WebDriver::Support::Select.new(driver.find_element(:tag_name, "select"))5select.select_by(:text, 'Ruby')Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
