From 81c82e58bb1912695c56c410aceac098b08404e3 Mon Sep 17 00:00:00 2001 From: titusfortner Date: Thu, 6 Jun 2024 07:28:49 -0500 Subject: [PATCH] [rb] create context manager and implement navigation with BiDi --- rb/lib/selenium/webdriver/bidi.rb | 1 + .../webdriver/bidi/browsing_context.rb | 4 ++ .../webdriver/bidi/context_manager.rb | 59 +++++++++++++++++ .../selenium/webdriver/remote/bidi_bridge.rb | 22 +++++++ .../selenium/webdriver/navigation_spec.rb | 63 ++++++++++--------- 5 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 rb/lib/selenium/webdriver/bidi/context_manager.rb diff --git a/rb/lib/selenium/webdriver/bidi.rb b/rb/lib/selenium/webdriver/bidi.rb index 0beb1d024578a..4c80e516f382c 100644 --- a/rb/lib/selenium/webdriver/bidi.rb +++ b/rb/lib/selenium/webdriver/bidi.rb @@ -24,6 +24,7 @@ class BiDi autoload :LogInspector, 'selenium/webdriver/bidi/log_inspector' autoload :LogHandler, 'selenium/webdriver/bidi/log_handler' autoload :BrowsingContext, 'selenium/webdriver/bidi/browsing_context' + autoload :ContextManager, 'selenium/webdriver/bidi/context_manager' autoload :Struct, 'selenium/webdriver/bidi/struct' def initialize(url:) diff --git a/rb/lib/selenium/webdriver/bidi/browsing_context.rb b/rb/lib/selenium/webdriver/bidi/browsing_context.rb index 8e4eaa1434e0b..3b34d8b2b25a7 100644 --- a/rb/lib/selenium/webdriver/bidi/browsing_context.rb +++ b/rb/lib/selenium/webdriver/bidi/browsing_context.rb @@ -33,6 +33,10 @@ class BrowsingContext }.freeze def initialize(driver:, browsing_context_id: nil, type: nil, reference_context: nil) + WebDriver.logger.deprecate('BrowsingContext class', + 'ContextManager or driver.navigate', + id: :browsing_context) + unless driver.capabilities.web_socket_url raise Error::WebDriverError, 'WebDriver instance must support BiDi protocol' diff --git a/rb/lib/selenium/webdriver/bidi/context_manager.rb b/rb/lib/selenium/webdriver/bidi/context_manager.rb new file mode 100644 index 0000000000000..8f4a93561dd3e --- /dev/null +++ b/rb/lib/selenium/webdriver/bidi/context_manager.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +# Licensed to the Software Freedom Conservancy (SFC) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The SFC licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +require_relative 'navigate_result' +require_relative 'browsing_context_info' + +module Selenium + module WebDriver + class BiDi + class ContextManager + READINESS_STATE = { + none: 'none', + eager: 'interactive', + normal: 'complete' + }.freeze + + def initialize(bridge) + @bridge = bridge + @bidi = @bridge.bidi + page_load_strategy = bridge.capabilities[:page_load_strategy] + @readiness = READINESS_STATE[page_load_strategy] + end + + def navigate(url, context_id: nil) + context_id ||= @bridge.window_handle + @bidi.send_cmd('browsingContext.navigate', context: context_id, url: url, wait: @readiness) + end + + # Positive values go forwards, negative values go backwards + def traverse_history(delta, context_id: nil) + context_id ||= @bridge.window_handle + @bidi.send_cmd('browsingContext.traverseHistory', context: context_id, delta: delta) + end + + def reload(context_id: nil, ignore_cache: false) + context_id ||= @bridge.window_handle + params = {context: context_id, ignore_cache: ignore_cache, wait: @readiness} + @bidi.send_cmd('browsingContext.reload', **params) + end + end + end # BiDi + end # WebDriver +end # Selenium diff --git a/rb/lib/selenium/webdriver/remote/bidi_bridge.rb b/rb/lib/selenium/webdriver/remote/bidi_bridge.rb index 4207577cf14dc..9b2bdae72b27a 100644 --- a/rb/lib/selenium/webdriver/remote/bidi_bridge.rb +++ b/rb/lib/selenium/webdriver/remote/bidi_bridge.rb @@ -29,6 +29,22 @@ def create_session(capabilities) @bidi = Selenium::WebDriver::BiDi.new(url: socket_url) end + def get(url) + context_manager.navigate(url) + end + + def go_back + context_manager.traverse_history(-1) + end + + def go_forward + context_manager.traverse_history(1) + end + + def refresh + context_manager.reload + end + def quit super ensure @@ -38,6 +54,12 @@ def quit def close execute(:close_window).tap { |handles| bidi.close if handles.empty? } end + + private + + def context_manager + @context_manager ||= WebDriver::BiDi::ContextManager.new(self) + end end # BiDiBridge end # Remote end # WebDriver diff --git a/rb/spec/integration/selenium/webdriver/navigation_spec.rb b/rb/spec/integration/selenium/webdriver/navigation_spec.rb index b7586bc1bb9d8..1f7f5506c4b4b 100644 --- a/rb/spec/integration/selenium/webdriver/navigation_spec.rb +++ b/rb/spec/integration/selenium/webdriver/navigation_spec.rb @@ -18,43 +18,46 @@ # under the License. require_relative 'spec_helper' +module Selenium + module WebDriver + describe Navigation do + it 'navigates back and forward' do + form_title = 'We Leave From Here' + result_title = 'We Arrive Here' + form_url = url_for 'formPage.html' + result_url = url_for 'resultPage.html' -describe 'Navigation', exclusive: {bidi: false, reason: 'Not yet implemented with BiDi'} do - it 'navigates back and forward' do - form_title = 'We Leave From Here' - result_title = 'We Arrive Here' - form_url = url_for 'formPage.html' - result_url = url_for 'resultPage.html' + driver.navigate.to form_url + expect(driver.title).to eq(form_title) - driver.navigate.to form_url - expect(driver.title).to eq(form_title) + driver.find_element(id: 'imageButton').click + wait.until { driver.title != form_title } - driver.find_element(id: 'imageButton').click - wait.until { driver.title != form_title } + expect(driver.current_url).to include(result_url) + expect(driver.title).to eq(result_title) - expect(driver.current_url).to include(result_url) - expect(driver.title).to eq(result_title) + driver.navigate.back - driver.navigate.back + expect(driver.current_url).to include(form_url) + expect(driver.title).to eq(form_title) - expect(driver.current_url).to include(form_url) - expect(driver.title).to eq(form_title) + driver.navigate.forward + expect(driver.current_url).to include(result_url) + expect(driver.title).to eq(result_title) + end - driver.navigate.forward - expect(driver.current_url).to include(result_url) - expect(driver.title).to eq(result_title) - end + it 'refreshes the page' do + changed_title = 'Changed' - it 'refreshes the page' do - changed_title = 'Changed' + driver.navigate.to url_for('javascriptPage.html') + driver.find_element(link_text: 'Change the page title!').click + expect(driver.title).to eq(changed_title) - driver.navigate.to url_for('javascriptPage.html') - driver.find_element(link_text: 'Change the page title!').click - expect(driver.title).to eq(changed_title) + driver.navigate.refresh + wait.until { driver.title != changed_title } - driver.navigate.refresh - wait.until { driver.title != changed_title } - - expect(driver.title).to eq('Testing Javascript') - end -end + expect(driver.title).to eq('Testing Javascript') + end + end + end # WebDriver +end # Selenium