Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rb] implement navigation commands with BiDi #14094

Merged
merged 8 commits into from
Nov 20, 2024
1 change: 1 addition & 0 deletions rb/lib/selenium/webdriver/bidi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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:)
Expand Down
4 changes: 4 additions & 0 deletions rb/lib/selenium/webdriver/bidi/browsing_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
60 changes: 60 additions & 0 deletions rb/lib/selenium/webdriver/bidi/context_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 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
titusfortner marked this conversation as resolved.
Show resolved Hide resolved
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
puts "READINESS - #{@readiness}"
titusfortner marked this conversation as resolved.
Show resolved Hide resolved
@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
22 changes: 22 additions & 0 deletions rb/lib/selenium/webdriver/remote/bidi_bridge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
63 changes: 33 additions & 30 deletions rb/spec/integration/selenium/webdriver/navigation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading