diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 5b10b6e4a52a3..9999a6d905124 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -119,6 +119,9 @@ jobs: uses: browser-actions/setup-edge@latest with: edge-version: ${{ inputs.browser-version || 'stable' }} + - name: Setup Safari + if: inputs.browser == 'safari' + run: sudo safaridriver --enable - name: Run Bazel run: ${{ inputs.run }} - name: Start SSH session diff --git a/.github/workflows/ci-ruby.yml b/.github/workflows/ci-ruby.yml index 5a09e011e4631..80ced414f5fef 100644 --- a/.github/workflows/ci-ruby.yml +++ b/.github/workflows/ci-ruby.yml @@ -45,6 +45,8 @@ jobs: os: windows - ruby-version: 3.2.0 os: ubuntu + - ruby-version: 3.2.0 + os: macos - ruby-version: jruby-9.4.0.0 os: ubuntu - ruby-version: truffleruby-22.3.0 @@ -67,12 +69,20 @@ jobs: - chrome - edge - firefox + - safari os: - ubuntu - windows + - macos exclude: - browser: edge os: ubuntu + - browser: edge + os: macos + - browser: safari + os: ubuntu + - browser: safari + os: windows with: name: Local Tests (${{ matrix.browser }}, ${{ matrix.os }}) browser: ${{ matrix.browser }} @@ -96,12 +106,20 @@ jobs: - chrome - edge - firefox + - safari os: - ubuntu - windows + - macos exclude: - browser: edge os: ubuntu + - browser: edge + os: macos + - browser: safari + os: ubuntu + - browser: safari + os: windows with: name: Remote Tests (${{ matrix.browser }}, ${{ matrix.os }}) browser: ${{ matrix.browser }} diff --git a/rb/spec/integration/selenium/webdriver/action_builder_spec.rb b/rb/spec/integration/selenium/webdriver/action_builder_spec.rb index 457a89e1ea7ab..6dd6f198d8ba3 100644 --- a/rb/spec/integration/selenium/webdriver/action_builder_spec.rb +++ b/rb/spec/integration/selenium/webdriver/action_builder_spec.rb @@ -163,7 +163,7 @@ module WebDriver expect(element.attribute(:value)).to eq('DoubleClicked') end - it 'executes with equivalent pointer methods' do + it 'executes with equivalent pointer methods', except: {browser: %i[safari safari_preview]} do driver.navigate.to url_for('javascriptPage.html') element = driver.find_element(id: 'doubleClickField') @@ -203,8 +203,7 @@ module WebDriver end it 'moves to element with offset', except: {browser: :firefox, - ci: :github, - platform: :windows, + platform: %i[windows macosx], reason: 'Some issues with resolution?'} do driver.navigate.to url_for('javascriptPage.html') origin = driver.find_element(id: 'keyUpArea') @@ -263,7 +262,8 @@ module WebDriver end end - describe 'pen stylus', except: {browser: :firefox, reason: 'Unknown pointerType'} do + describe 'pen stylus', except: [{browser: :firefox, reason: 'Unknown pointerType'}, + {browser: :safari, reason: 'Some issues with resolution?'}] do it 'sets pointer event properties' do driver.navigate.to url_for('pointerActionsPage.html') pointer_area = driver.find_element(id: 'pointerArea') @@ -318,10 +318,9 @@ module WebDriver end end - describe '#scroll_by', only: {browser: %i[chrome edge firefox]} do + describe '#scroll_by' do it 'scrolls by given amount', except: {browser: :firefox, platform: :macosx, - headless: false, reason: 'scrolls insufficient number of pixels'} do driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') footer = driver.find_element(tag_name: 'footer') @@ -334,9 +333,9 @@ module WebDriver end end - describe '#scroll_from', only: {browser: %i[chrome edge firefox]} do + describe '#scroll_from' do it 'scrolls from element by given amount', - except: {browser: :firefox, reason: 'incorrect MoveTargetOutOfBoundsError'} do + except: {browser: %i[firefox safari], reason: 'incorrect MoveTargetOutOfBoundsError'} do driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') iframe = driver.find_element(tag_name: 'iframe') scroll_origin = WheelActions::ScrollOrigin.element(iframe) @@ -350,7 +349,7 @@ module WebDriver end it 'scrolls from element by given amount with offset', - except: {browser: :firefox, reason: 'incorrect MoveTargetOutOfBoundsError'} do + except: {browser: %i[firefox safari], reason: 'incorrect MoveTargetOutOfBoundsError'} do driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') footer = driver.find_element(tag_name: 'footer') scroll_origin = WheelActions::ScrollOrigin.element(footer, 0, -50) @@ -387,7 +386,8 @@ module WebDriver expect(in_viewport?(checkbox)).to be true end - it 'raises MoveTargetOutOfBoundsError when origin offset is out of viewport' do + it 'raises MoveTargetOutOfBoundsError when origin offset is out of viewport', + only: {browser: %i[chrome edge firefox]} do driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame.html') scroll_origin = WheelActions::ScrollOrigin.viewport(-10, -10) diff --git a/rb/spec/integration/selenium/webdriver/bidi_spec.rb b/rb/spec/integration/selenium/webdriver/bidi_spec.rb index 497f066ad74df..7604bd1cfb504 100644 --- a/rb/spec/integration/selenium/webdriver/bidi_spec.rb +++ b/rb/spec/integration/selenium/webdriver/bidi_spec.rb @@ -36,7 +36,7 @@ module WebDriver expect(status.message).not_to be_empty end - it 'can navigate and listen to errors', except: {browser: %i[chrome edge], reason: 'not yet implemented'} do + it 'can navigate and listen to errors' do log_entry = nil log_inspector = BiDi::LogInspector.new(driver) log_inspector.on_javascript_exception { |log| log_entry = log } @@ -45,10 +45,12 @@ module WebDriver info = browsing_context.navigate(url: url_for('/bidi/logEntryAdded.html')) expect(browsing_context.id).not_to be_nil - expect(info.navigation_id).to be_nil + expect(info.navigation_id).not_to be_nil expect(info.url).to include('/bidi/logEntryAdded.html') - driver.find_element(id: 'jsException').click + js_exception = wait.until { driver.find_element(id: 'jsException') } + js_exception.click + wait.until { !log_entry.nil? } expect(log_entry).to have_attributes( diff --git a/rb/spec/integration/selenium/webdriver/chrome/driver_spec.rb b/rb/spec/integration/selenium/webdriver/chrome/driver_spec.rb index 737f5126c8747..a6fb7da579df3 100644 --- a/rb/spec/integration/selenium/webdriver/chrome/driver_spec.rb +++ b/rb/spec/integration/selenium/webdriver/chrome/driver_spec.rb @@ -52,10 +52,8 @@ module Chrome end describe 'PrintsPage' do - before(:all) do - @headless = ENV.delete('HEADLESS') - reset_driver!(args: ['--headless']) - end + before(:all) { @headless = ENV.delete('HEADLESS') } + before { reset_driver!(args: ['--headless']) } after(:all) do quit_driver diff --git a/rb/spec/integration/selenium/webdriver/driver_spec.rb b/rb/spec/integration/selenium/webdriver/driver_spec.rb index 2515ff727ca3a..5a5e748731c52 100644 --- a/rb/spec/integration/selenium/webdriver/driver_spec.rb +++ b/rb/spec/integration/selenium/webdriver/driver_spec.rb @@ -24,7 +24,7 @@ module WebDriver describe Driver do it_behaves_like 'driver that can be started concurrently', exclude: {browser: %i[safari safari_preview]} - it 'creates default capabilities' do + it 'creates default capabilities', exclude: {browser: %i[safari safari_preview]} do reset_driver! do |driver| caps = driver.capabilities expect(caps.proxy).to be_nil @@ -147,7 +147,8 @@ module WebDriver }.to raise_error(Error::NoSuchElementError, /errors#no-such-element-exception/) end - it 'raises if invalid locator' do + it 'raises if invalid locator', + exclude: {browser: %i[safari safari_preview], reason: 'Safari raises TimeoutError'} do driver.navigate.to url_for('xhtmlTest.html') expect { driver.find_element(xpath: '*?//-') diff --git a/rb/spec/integration/selenium/webdriver/firefox/driver_spec.rb b/rb/spec/integration/selenium/webdriver/firefox/driver_spec.rb index b0ce3807a108e..9ec85e2479ed8 100644 --- a/rb/spec/integration/selenium/webdriver/firefox/driver_spec.rb +++ b/rb/spec/integration/selenium/webdriver/firefox/driver_spec.rb @@ -44,11 +44,9 @@ module Firefox page: {width: 30})).to include(magic_number) end - it 'prints full page', except: [{ci: :github, - platform: :windows, + it 'prints full page', except: [{platform: :windows, reason: 'Some issues with resolution?'}, {platform: :macosx, - headless: true, reason: 'showing half resolution of what expected'}] do viewport_width = driver.execute_script('return window.innerWidth;') viewport_height = driver.execute_script('return window.innerHeight;') diff --git a/rb/spec/integration/selenium/webdriver/manager_spec.rb b/rb/spec/integration/selenium/webdriver/manager_spec.rb index cf1708a5f00cf..600ebc68261c3 100644 --- a/rb/spec/integration/selenium/webdriver/manager_spec.rb +++ b/rb/spec/integration/selenium/webdriver/manager_spec.rb @@ -134,7 +134,7 @@ module WebDriver end describe 'sameSite' do - it 'allows adding with value Strict', only: {browser: %i[chrome edge firefox]} do + it 'allows adding with value Strict' do driver.manage.add_cookie name: 'samesite', value: 'strict', same_site: 'Strict' @@ -142,7 +142,7 @@ module WebDriver expect(driver.manage.cookie_named('samesite')[:same_site]).to eq('Strict') end - it 'allows adding with value Lax', only: {browser: %i[chrome edge firefox]} do + it 'allows adding with value Lax' do driver.manage.add_cookie name: 'samesite', value: 'lax', same_site: 'Lax' diff --git a/rb/spec/integration/selenium/webdriver/safari/driver_spec.rb b/rb/spec/integration/selenium/webdriver/safari/driver_spec.rb index c936217809e6a..541e35ef4fdb9 100644 --- a/rb/spec/integration/selenium/webdriver/safari/driver_spec.rb +++ b/rb/spec/integration/selenium/webdriver/safari/driver_spec.rb @@ -36,13 +36,13 @@ module Safari Safari.use_technology_preview = nil end - it 'sets before options', exclusive: {browser: :safari} do + it 'sets before options', exclusive: {browser: :safari_preview} do Safari.technology_preview! local_driver = WebDriver.for :safari expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview' end - it 'sets after options' do + it 'sets after options', exclusive: {browser: :safari_preview} do options = Options.safari Safari.technology_preview! local_driver = WebDriver.for :safari, options: options diff --git a/rb/spec/integration/selenium/webdriver/select_spec.rb b/rb/spec/integration/selenium/webdriver/select_spec.rb index ca689a944a47c..715dbe5e7ba89 100644 --- a/rb/spec/integration/selenium/webdriver/select_spec.rb +++ b/rb/spec/integration/selenium/webdriver/select_spec.rb @@ -109,7 +109,8 @@ module Support expect(selected_options).to include(driver.find_element(css: 'option[value="onion gravy"]')) end - it 'errors when option disabled' do + it 'errors when option disabled', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do expect { multi_disabled.select_by(:text, 'Disabled') }.to raise_exception(Error::UnsupportedOperationError) @@ -137,7 +138,8 @@ module Support expect(selected_options).to include(driver.find_element(css: 'option[value=ham]')) end - it 'errors when option disabled' do + it 'errors when option disabled', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do expect { multi_disabled.select_by(:index, 1) }.to raise_exception(Error::UnsupportedOperationError) end @@ -163,7 +165,8 @@ module Support expect(selected_options).to include(driver.find_element(css: 'option[value=ham]')) end - it 'errors when option disabled' do + it 'errors when option disabled', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do expect { multi_disabled.select_by(:value, 'disabled') }.to raise_exception(Error::UnsupportedOperationError) @@ -197,7 +200,8 @@ module Support expect(select.selected_options).to eq([expected_option]) end - it 'errors when option disabled' do + it 'errors when option disabled', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do expect { single_disabled.select_by(:text, 'Disabled') }.to raise_exception(Error::UnsupportedOperationError) @@ -223,7 +227,8 @@ module Support expect(selected_options).to eq([driver.find_element(css: 'option[value="two"]')]) end - it 'errors when option disabled' do + it 'errors when option disabled', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do expect { single_disabled.select_by(:index, 1) }.to raise_exception(Error::UnsupportedOperationError) end @@ -247,7 +252,8 @@ module Support expect(selected_options).to eq([driver.find_element(css: 'option[value="two"]')]) end - it 'errors when option disabled' do + it 'errors when option disabled', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do expect { single_disabled.select_by(:value, 'disabled') }.to raise_exception(Error::UnsupportedOperationError) @@ -345,7 +351,8 @@ module Support expect { select.select_all }.to raise_exception(Error::UnsupportedOperationError) end - it 'raises exception if select contains disabled options' do + it 'raises exception if select contains disabled options', + exclude: {browser: :safari, reason: 'Safari raises no exception with disabled'} do select = described_class.new(driver.find_element(name: 'multi_disabled')) expect { select.select_all }.to raise_exception(Error::UnsupportedOperationError) diff --git a/rb/spec/integration/selenium/webdriver/shadow_root_spec.rb b/rb/spec/integration/selenium/webdriver/shadow_root_spec.rb index 912c91b1c34af..91b9f889dccbc 100644 --- a/rb/spec/integration/selenium/webdriver/shadow_root_spec.rb +++ b/rb/spec/integration/selenium/webdriver/shadow_root_spec.rb @@ -21,7 +21,7 @@ module Selenium module WebDriver - describe ShadowRoot, only: {browser: %i[chrome firefox edge]} do + describe ShadowRoot, only: {browser: %i[chrome firefox edge safari]} do before { driver.navigate.to url_for('webComponents.html') } let(:custom_element) { driver.find_element(css: 'custom-checkbox-element') } @@ -31,13 +31,14 @@ module WebDriver expect(shadow_root).to be_a described_class end - it 'raises error if no shadow root' do + it 'raises error if no shadow root', exclude: {browser: :safari, reason: 'NoMethodError'} do driver.navigate.to url_for('simpleTest.html') div = driver.find_element(css: 'div') expect { div.shadow_root }.to raise_error(Error::NoSuchShadowRootError) end - it 'gets shadow root from script' do + it 'gets shadow root from script', + exclude: {browser: :safari, reason: 'returns correct node, but references shadow root as a element'} do shadow_root = custom_element.shadow_root execute_shadow_root = driver.execute_script('return arguments[0].shadowRoot;', custom_element) expect(execute_shadow_root).to eq shadow_root @@ -51,7 +52,7 @@ module WebDriver expect(element).to be_a Element end - it 'by xpath', except: {browser: %i[chrome edge firefox], + it 'by xpath', except: {browser: %i[chrome edge firefox safari], reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=4097'} do shadow_root = custom_element.shadow_root element = shadow_root.find_element(xpath: "//input[type='checkbox']") @@ -73,7 +74,7 @@ module WebDriver expect(element).to be_a Element end - it 'by tag name', except: {browser: %i[chrome edge firefox], + it 'by tag name', except: {browser: %i[chrome edge firefox safari], reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=4097'} do shadow_root = custom_element.shadow_root element = shadow_root.find_element(tag_name: 'input') @@ -97,7 +98,7 @@ module WebDriver expect(elements.first).to be_a Element end - it 'by xpath', except: {browser: %i[chrome edge firefox], + it 'by xpath', except: {browser: %i[chrome edge firefox safari], reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=4097'} do shadow_root = custom_element.shadow_root elements = shadow_root.find_elements(xpath: "//input[type='checkbox']") @@ -122,7 +123,7 @@ module WebDriver expect(elements.first).to be_a Element end - it 'by tag name', except: {browser: %i[chrome edge firefox], + it 'by tag name', except: {browser: %i[chrome edge firefox safari], reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=4097'} do shadow_root = custom_element.shadow_root elements = shadow_root.find_elements(tag_name: 'input') diff --git a/rb/spec/integration/selenium/webdriver/spec_support/shared_examples/concurrent_driver.rb b/rb/spec/integration/selenium/webdriver/spec_support/shared_examples/concurrent_driver.rb index cf9ce8d7e1545..e3728572e5efd 100644 --- a/rb/spec/integration/selenium/webdriver/spec_support/shared_examples/concurrent_driver.rb +++ b/rb/spec/integration/selenium/webdriver/spec_support/shared_examples/concurrent_driver.rb @@ -23,7 +23,8 @@ before { quit_driver } - after do + after do |example| + skip if example.metadata[:skip] drivers.each(&:quit) threads.select(&:alive?).each(&:kill) create_driver! diff --git a/rb/spec/integration/selenium/webdriver/takes_screenshot_spec.rb b/rb/spec/integration/selenium/webdriver/takes_screenshot_spec.rb index c9843279ac200..884cde1440b91 100644 --- a/rb/spec/integration/selenium/webdriver/takes_screenshot_spec.rb +++ b/rb/spec/integration/selenium/webdriver/takes_screenshot_spec.rb @@ -95,11 +95,9 @@ def save_screenshot_and_assert(source, path) expect(height).to be <= viewport_height end - it 'takes full page screenshot', except: [{ci: :github, - platform: :windows, + it 'takes full page screenshot', except: [{platform: :windows, reason: 'Some issues with resolution?'}, {platform: :macosx, - headless: true, reason: 'showing half resolution of what expected'}], exclusive: {browser: :firefox} do viewport_width = driver.execute_script('return window.innerWidth;') diff --git a/rb/spec/integration/selenium/webdriver/window_spec.rb b/rb/spec/integration/selenium/webdriver/window_spec.rb index 7cc1ac56db899..e8a912abfda57 100644 --- a/rb/spec/integration/selenium/webdriver/window_spec.rb +++ b/rb/spec/integration/selenium/webdriver/window_spec.rb @@ -124,7 +124,8 @@ module WebDriver expect(new_size.height).to be > old_size.height end - it 'can minimize the window', except: {browser: %i[chrome edge], headless: true} do + it 'can minimize the window', except: [{browser: %i[chrome edge], headless: true}, + {browser: :safari, ci: :github}] do window.minimize expect { wait.until { driver.execute_script('return document.hidden;') }