diff --git a/rb/lib/selenium/webdriver/bidi/browser.rb b/rb/lib/selenium/webdriver/bidi/browser.rb index d69bb269d37d7..aa9a9020af589 100644 --- a/rb/lib/selenium/webdriver/bidi/browser.rb +++ b/rb/lib/selenium/webdriver/bidi/browser.rb @@ -17,6 +17,8 @@ # specific language governing permissions and limitations # under the License. +require_relative 'browser/window' + module Selenium module WebDriver class BiDi @@ -28,13 +30,9 @@ class BiDi # class Browser - Window = Struct.new(:handle, :active, :height, :width, :x, :y, :state) do - def active? - active - end - end def initialize(bidi) @bidi = bidi + @window = nil end def create_user_context @@ -62,9 +60,13 @@ def windows y: win_data['y'], state: win_data['state'] } - Window.new(**attributes) + Window.new(@bidi, **attributes) end end + + def window + @window ||= windows.find(&:active?) || windows.first + end end # Browser end # BiDi end # WebDriver diff --git a/rb/lib/selenium/webdriver/bidi/browser/window.rb b/rb/lib/selenium/webdriver/bidi/browser/window.rb new file mode 100644 index 0000000000000..1743f44df104b --- /dev/null +++ b/rb/lib/selenium/webdriver/bidi/browser/window.rb @@ -0,0 +1,80 @@ +# 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. + +module Selenium + module WebDriver + class BiDi + class Browser + class Window + attr_reader :handle, :active, :state + attr_accessor :height, :width, :x, :y + + def initialize(bidi, **opts) + @bidi = bidi + @handle = opts[:handle] + @active = opts[:active] + @height = opts[:height].to_i + @width = opts[:width].to_i + @x = opts[:x].to_i + @y = opts[:y].to_i + @state = opts[:state].to_sym + end + + def active? + @active + end + + def set_state(state:, width: nil, height: nil, x: nil, y: nil) + params = {clientWindow: @handle, state: state.to_s, width: width, height: height, x: x, y: y}.compact + + response = @bidi.send_cmd('browser.setClientWindowState', **params) + update_attributes(state: state, width: width, height: height, x: x, y: y) + response + end + + def maximize + set_state(state: :maximized) + end + + def minimize + set_state(state: :minimized) + end + + def fullscreen + set_state(state: :fullscreen) + end + + def resize(width:, height:, x: nil, y: nil) + set_state(state: :normal, width: width, height: height, x: x, y: y) + end + + private + + def update_attributes(state:, width:, height:, x:, y:) + @state = state.to_sym + @width = width.to_i if width + @height = height.to_i if height + @x = x.to_i if x + @y = y.to_i if y + end + end # Window + end # Browser + end # BiDi + end # WebDriver +end # Selenium diff --git a/rb/sig/lib/selenium/webdriver/bidi/browser.rbs b/rb/sig/lib/selenium/webdriver/bidi/browser.rbs index a2e51e3d21004..fc1b36fa95526 100644 --- a/rb/sig/lib/selenium/webdriver/bidi/browser.rbs +++ b/rb/sig/lib/selenium/webdriver/bidi/browser.rbs @@ -2,17 +2,20 @@ module Selenium module WebDriver class BiDi class Browser - Window: Selenium::WebDriver::BiDi::Browser::Window - @bidi: BiDi + @window: Window? def initialize: (BiDi bidi) -> void def create_user_context: () -> Hash[String, String] - def user_contexts: () -> Array[Hash[String, String]] + def user_contexts: () -> Hash[String, Array[Hash[String, String]]] + + def remove_user_context: (String user_context) -> Hash[untyped, untyped] + + def windows: () -> Array[Window] - def remove_user_context: (String user_context) -> Hash[nil, nil] + def window: () -> Window? end end end diff --git a/rb/sig/lib/selenium/webdriver/bidi/browser/window.rbs b/rb/sig/lib/selenium/webdriver/bidi/browser/window.rbs new file mode 100644 index 0000000000000..613dfb2aa9ccc --- /dev/null +++ b/rb/sig/lib/selenium/webdriver/bidi/browser/window.rbs @@ -0,0 +1,45 @@ +module Selenium + module WebDriver + class BiDi + class Browser + class Window + attr_reader handle: String + attr_reader active: bool + attr_reader state: Symbol + + attr_accessor height: Integer + attr_accessor width: Integer + attr_accessor x: Integer + attr_accessor y: Integer + + @bidi: BiDi + @handle: String + @active: bool + @state: Symbol + @height: Integer + @width: Integer + @x: Integer + @y: Integer + + def initialize: (BiDi bidi, handle: String, active: bool, height: Integer, width: Integer, x: Integer, y: Integer, state: String) -> void + + def active?: () -> bool + + def set_state: (state: String | Symbol, ?width: Integer?, ?height: Integer?, ?x: Integer?, ?y: Integer?) -> Hash[untyped, untyped] + + def maximize: () -> Hash[untyped, untyped] + + def minimize: () -> Hash[untyped, untyped] + + def fullscreen: () -> Hash[untyped, untyped] + + def resize: (width: Integer, height: Integer, ?x: Integer?, ?y: Integer?) -> Hash[untyped, untyped] + + private + + def update_attributes: (state: String | Symbol, width: Integer?, height: Integer?, x: Integer?, y: Integer?) -> void + end + end + end + end +end diff --git a/rb/spec/integration/selenium/webdriver/bidi/browser_spec.rb b/rb/spec/integration/selenium/webdriver/bidi/browser_spec.rb index 9f535cb1649a3..414ba00f3ee4a 100644 --- a/rb/spec/integration/selenium/webdriver/bidi/browser_spec.rb +++ b/rb/spec/integration/selenium/webdriver/bidi/browser_spec.rb @@ -73,6 +73,57 @@ class BiDi expect(active_window).to be_a(Selenium::WebDriver::BiDi::Browser::Window) end + + # Skip all browsers until browser.setClientWindowState is implemented + it 'maximizes window', except: {browser: %i[chrome edge firefox]} do + browser = described_class.new(bidi) + window = browser.window + + window.maximize + expect(window.state).to eq(:maximized) + end + + # Skip all browsers until browser.setClientWindowState is implemented + it 'minimizes window', except: {browser: %i[chrome edge firefox]} do + browser = described_class.new(bidi) + window = browser.window + + window.minimize + expect(window.state).to eq(:minimized) + end + + # Skip all browsers until browser.setClientWindowState is implemented + it 'sets window to fullscreen', except: {browser: %i[chrome edge firefox]} do + browser = described_class.new(bidi) + window = browser.window + + window.fullscreen + expect(window.state).to eq(:fullscreen) + end + + # Skip all browsers until browser.setClientWindowState is implemented + it 'resizes window', except: {browser: %i[chrome edge firefox]} do + browser = described_class.new(bidi) + window = browser.window + + window.resize(width: 800, height: 600) + expect(window.state).to eq(:normal) + expect(window.width).to eq(800) + expect(window.height).to eq(600) + end + + # Skip all browsers until browser.setClientWindowState is implemented + it 'sets window state with position', except: {browser: %i[chrome edge firefox]} do + browser = described_class.new(bidi) + window = browser.window + + window.set_state(state: :normal, width: 1024, height: 768, x: 100, y: 50) + expect(window.state).to eq(:normal) + expect(window.width).to eq(1024) + expect(window.height).to eq(768) + expect(window.x).to eq(100) + expect(window.y).to eq(50) + end end end end