From 74b7746e984cfbac0b4ab5beccb993772db78bd8 Mon Sep 17 00:00:00 2001 From: titusfortner Date: Sun, 15 May 2022 13:34:46 -0500 Subject: [PATCH 1/2] implement wheel tests --- .../SeleniumDocs/ActionsApi/WheelTest.cs | 122 ++++++++++++++++++ .../dev/selenium/actions_api/WheelTest.java | 103 +++++++++++++++ examples/javascript/actionsApi/wheelTest.js | 11 ++ .../dev/selenium/actions_api/WheelTest.kt | 103 +++++++++++++++ .../python/tests/actions_api/test_wheel.py | 71 ++++++++++ examples/python/tests/conftest.py | 26 ++++ examples/ruby/spec/actions_api/wheel_spec.rb | 78 +++++++++++ 7 files changed, 514 insertions(+) create mode 100644 examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs create mode 100644 examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java create mode 100644 examples/javascript/actionsApi/wheelTest.js create mode 100644 examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt create mode 100644 examples/python/tests/actions_api/test_wheel.py create mode 100644 examples/python/tests/conftest.py create mode 100644 examples/ruby/spec/actions_api/wheel_spec.rb diff --git a/examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs b/examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs new file mode 100644 index 000000000000..3c8c8a518e67 --- /dev/null +++ b/examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs @@ -0,0 +1,122 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using OpenQA.Selenium; +using OpenQA.Selenium.Chrome; + +namespace SeleniumDocs.GettingStarted +{ + [TestClass] + public class FirstScriptTest + { + public IWebDriver driver; + + [TestInitialize] + public void Setup() + { + driver = new ChromeDriver(); + } + + [TestCleanup] + public void Teardown() + { + driver?.Quit(); + } + + [TestMethod] + public void ShouldAllowScrollingToAnElement() + { + driver.Navigate().GoToUrl("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + + driver.Url = scrollFrameOutOfViewport; + IWebElement iframe = driver.FindElement(By.TagName("iframe")); + + Assert.IsFalse(IsInViewport(iframe)); + + new Actions(driver).ScrollToElement(iframe).Build().Perform(); + + Assert.IsTrue(IsInViewport(iframe)); + } + + [TestMethod] + public void ShouldAllowScrollingFromViewportByGivenAmount() + { + driver.Navigate().GoToUrl("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + IWebElement footer = driver.FindElement(By.TagName("footer")); + int deltaY = footer.Location.Y; + + new Actions(driver).ScrollByAmount(0, deltaY).Build().Perform(); + + Assert.IsTrue(IsInViewport(footer)); + } + + [TestMethod] + public void ShouldScrollFromElementByGivenAmount() + { + driver.Navigate().GoToUrl("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + IWebElement iframe = driver.FindElement(By.TagName("iframe")); + WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin + { + Element = iframe + }; + + new Actions(driver).ScrollFromOrigin(scrollOrigin, 0, 200).Build().Perform(); + + driver.SwitchTo().Frame(iframe); + IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox")); + Assert.IsTrue(IsInViewport(checkbox)); + } + + [TestMethod] + public void ShouldAllowScrollingFromElementByGivenAmountWithOffset() + { + driver.Navigate().GoToUrl("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + IWebElement footer = driver.FindElement(By.TagName("footer")); + var scrollOrigin = new WheelInputDevice.ScrollOrigin + { + Element = footer, + XOffset = 0, + YOffset = -50 + }; + + new Actions(driver).ScrollFromOrigin(scrollOrigin, 0, 200).Build().Perform(); + + IWebElement iframe = driver.FindElement(By.TagName("iframe")); + driver.SwitchTo().Frame(iframe); + IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox")); + Assert.IsTrue(IsInViewport(checkbox)); + } + + [TestMethod] + public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin() + { + driver.Navigate().GoToUrl("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html"); + var scrollOrigin = new WheelInputDevice.ScrollOrigin + { + Viewport = true, + XOffset = 10, + YOffset = 10 + }; + + new Actions(driver).ScrollFromOrigin(scrollOrigin, 0, 200).Build().Perform(); + + IWebElement iframe = driver.FindElement(By.TagName("iframe")); + driver.SwitchTo().Frame(iframe); + IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox")); + Assert.IsTrue(IsInViewport(checkbox)); + } + + private bool IsInViewport(IWebElement element) + { + String script = + "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n" + + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n" + + "return f\n" + + "window.pageYOffset&&t+o>window.pageXOffset"; + IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor; + + return (bool)javascriptDriver.ExecuteScript(script, element); + } + + + } +} \ No newline at end of file diff --git a/examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java b/examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java new file mode 100644 index 000000000000..9d9d47b5b4ad --- /dev/null +++ b/examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java @@ -0,0 +1,103 @@ +package dev.selenium.actions_api; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.interactions.WheelInput; + +public class WheelTest { + public WebDriver driver; + + @BeforeEach + public void setup() { + driver = new ChromeDriver(); + } + + @AfterEach + public void quit() { + driver.quit(); + } + + @Test + public void shouldScrollToElement() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement iframe = driver.findElement(By.tagName("iframe")); + + Assertions.assertFalse(inViewport(iframe)); + + new Actions(driver).scrollToElement(iframe).perform(); + + Assertions.assertTrue(inViewport(iframe)); + } + + @Test + public void shouldScrollFromViewportByGivenAmount() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement footer = driver.findElement(By.tagName("footer")); + int deltaY = footer.getRect().y; + + new Actions(driver).scrollByAmount(0, deltaY).perform(); + + Assertions.assertTrue(inViewport(footer)); + } + + @Test + public void shouldScrollFromElementByGivenAmount() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement iframe = driver.findElement(By.tagName("iframe")); + WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe); + + new Actions(driver).scrollFromOrigin(scrollOrigin, 0, 200).perform(); + + driver.switchTo().frame(iframe); + WebElement checkbox = driver.findElement(By.name("scroll_checkbox")); + Assertions.assertTrue(inViewport(checkbox)); + } + + @Test + public void shouldScrollFromElementByGivenAmountWithOffset() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement footer = driver.findElement(By.tagName("footer")); + WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50); + + new Actions(driver).scrollFromOrigin(scrollOrigin,0, 200).perform(); + + WebElement iframe = driver.findElement(By.tagName("iframe")); + driver.switchTo().frame(iframe); + WebElement checkbox = driver.findElement(By.name("scroll_checkbox")); + Assertions.assertTrue(inViewport(checkbox)); + } + + @Test + public void shouldScrollFromViewportByGivenAmountFromOrigin() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html"); + WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10); + + new Actions(driver).scrollFromOrigin(scrollOrigin, 0, 200).perform(); + + WebElement iframe = driver.findElement(By.tagName("iframe")); + driver.switchTo().frame(iframe); + WebElement checkbox = driver.findElement(By.name("scroll_checkbox")); + Assertions.assertTrue(inViewport(checkbox)); + } + + private boolean inViewport(WebElement element) { + + String script = + "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n" + + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n" + + "return f\n" + + "window.pageYOffset&&t+o>window.pageXOffset"; + + return (boolean) ((JavascriptExecutor) driver).executeScript(script, element); + } +} diff --git a/examples/javascript/actionsApi/wheelTest.js b/examples/javascript/actionsApi/wheelTest.js new file mode 100644 index 000000000000..7d65cfcd161b --- /dev/null +++ b/examples/javascript/actionsApi/wheelTest.js @@ -0,0 +1,11 @@ +const {Builder, By, Key, until} = require('selenium-webdriver'); + +(async function scrolling() { + try { + let driver = await new Builder().forBrowser('chrome').build(); + + await driver.quit(); + } catch (error) { + console.log(error) + } +})(); \ No newline at end of file diff --git a/examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt b/examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt new file mode 100644 index 000000000000..d1d529b98cf5 --- /dev/null +++ b/examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt @@ -0,0 +1,103 @@ +package dev.selenium.getting_started + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.interactions.WheelInput; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class ScrollTest { + private lateinit var driver: WebDriver + + @BeforeEach + fun setupBrowser() { + driver = ChromeDriver() + } + + @AfterEach + fun cleanupBrowser() { + driver.quit() + } + + @Test + fun shouldScrollToElement() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement iframe = driver.findElement(By.tagName("iframe")); + + Assertions.assertFalse(inViewport(iframe)); + + new Actions(driver).scrollToElement(iframe).perform(); + + Assertions.assertTrue(inViewport(iframe)); + } + + @Test + fun shouldScrollFromElementByGivenAmount() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement iframe = driver.findElement(By.tagName("iframe")); + WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe); + + new Actions(driver).scrollFromOrigin(scrollOrigin, 0, 200).perform(); + + driver.switchTo().frame(iframe); + WebElement checkbox = driver.findElement(By.name("scroll_checkbox")); + Assertions.assertTrue(inViewport(checkbox)); + } + + @Test + fun shouldScrollFromElementByGivenAmountWithOffset() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement footer = driver.findElement(By.tagName("footer")); + WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50); + + new Actions(driver).scrollFromOrigin(scrollOrigin,0, 200).perform(); + + WebElement iframe = driver.findElement(By.tagName("iframe")); + driver.switchTo().frame(iframe); + WebElement checkbox = driver.findElement(By.name("scroll_checkbox")); + Assertions.assertTrue(inViewport(checkbox)); + } + + @Test + fun shouldScrollFromViewportByGivenAmount() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html"); + WebElement footer = driver.findElement(By.tagName("footer")); + int deltaY = footer.getRect().y; + + new Actions(driver).scrollByAmount(0, deltaY).perform(); + + Assertions.assertTrue(inViewport(footer)); + } + + @Test + fun shouldScrollFromViewportByGivenAmountFromOrigin() { + driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html"); + WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10); + + new Actions(driver).scrollFromOrigin(scrollOrigin, 0, 200).perform(); + + WebElement iframe = driver.findElement(By.tagName("iframe")); + driver.switchTo().frame(iframe); + WebElement checkbox = driver.findElement(By.name("scroll_checkbox")); + Assertions.assertTrue(inViewport(checkbox)); + } + + fun inViewport(WebElement element) { + String script = + "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n" + + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n" + + "return f\n" + + "window.pageYOffset&&t+o>window.pageXOffset"; + + return (boolean) ((JavascriptExecutor) driver).executeScript(script, element); + } +} \ No newline at end of file diff --git a/examples/python/tests/actions_api/test_wheel.py b/examples/python/tests/actions_api/test_wheel.py new file mode 100644 index 000000000000..93d85b09097b --- /dev/null +++ b/examples/python/tests/actions_api/test_wheel.py @@ -0,0 +1,71 @@ +from selenium.webdriver import ActionChains +from selenium.webdriver.common.by import By +from selenium.webdriver.common.actions.wheel_input import ScrollOrigin + + +def test_can_scroll_to_element(driver): + driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") + iframe = driver.find_element(By.TAG_NAME, "iframe") + + assert not _in_viewport(driver, iframe) + + ActionChains(driver).scroll_to_element(iframe).perform() + + assert _in_viewport(driver, iframe) + + +def test_can_scroll_from_viewport_by_amount(driver): + driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") + footer = driver.find_element(By.TAG_NAME, "footer") + delta_y = footer.rect['y'] + + ActionChains(driver).scroll_by_amount(0, delta_y).pause(0.2).perform() + + assert _in_viewport(driver, footer) + + +def test_can_scroll_from_element_by_amount(driver): + driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") + iframe = driver.find_element(By.TAG_NAME, "iframe") + scroll_origin = ScrollOrigin.from_element(iframe) + + ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform() + + driver.switch_to.frame(iframe) + checkbox = driver.find_element(By.NAME, "scroll_checkbox") + assert _in_viewport(driver, checkbox) + + +def test_can_scroll_from_element_with_offset_by_amount(driver): + driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html") + footer = driver.find_element(By.TAG_NAME, "footer") + scroll_origin = ScrollOrigin.from_element(footer, 0, -50) + + ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform() + + iframe = driver.find_element(By.TAG_NAME, "iframe") + driver.switch_to.frame(iframe) + checkbox = driver.find_element(By.NAME, "scroll_checkbox") + assert _in_viewport(driver, checkbox) + + +def test_can_scroll_from_viewport_with_offset_by_amount(driver): + driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html") + scroll_origin = ScrollOrigin.from_viewport(10, 10) + + ActionChains(driver).scroll_from_origin(scroll_origin, 0, 200).pause(0.2).perform() + + iframe = driver.find_element(By.TAG_NAME, "iframe") + driver.switch_to.frame(iframe) + checkbox = driver.find_element(By.NAME, "scroll_checkbox") + assert _in_viewport(driver, checkbox) + + +def _in_viewport(driver, element): + script = ( + "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n" + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n" + "return f\n" + "window.pageYOffset&&t+o>window.pageXOffset" + ) + return driver.execute_script(script, element) diff --git a/examples/python/tests/conftest.py b/examples/python/tests/conftest.py new file mode 100644 index 000000000000..886e2d90da73 --- /dev/null +++ b/examples/python/tests/conftest.py @@ -0,0 +1,26 @@ +# 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. +import pytest +from selenium import webdriver + + +@pytest.fixture(scope='function') +def driver(): + driver = webdriver.Chrome() + yield driver + + driver.quit() \ No newline at end of file diff --git a/examples/ruby/spec/actions_api/wheel_spec.rb b/examples/ruby/spec/actions_api/wheel_spec.rb new file mode 100644 index 000000000000..30afdf918165 --- /dev/null +++ b/examples/ruby/spec/actions_api/wheel_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Scrolling' do + let(:driver) { Selenium::WebDriver.for :chrome } + + after(:each) { driver.quit } + + it 'scrolls to element' do + driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') + iframe = driver.find_element(tag_name: 'iframe') + + expect(in_viewport?(iframe)).to eq false + + driver.action.scroll_to(iframe).perform + + expect(in_viewport?(iframe)).to eq true + end + + it 'scrolls by given amount' do + driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') + footer = driver.find_element(tag_name: 'footer') + delta_y = footer.rect.y + + driver.action.scroll_by(0, delta_y).perform + + expect(in_viewport?(footer)).to eq true + end + + it 'scrolls from element by given amount' do + driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html') + iframe = driver.find_element(tag_name: 'iframe') + scroll_origin = WheelActions::ScrollOrigin.element(iframe) + + driver.action.scroll_from(scroll_origin, 0, 200).perform + + driver.switch_to.frame(iframe) + checkbox = driver.find_element(name: 'scroll_checkbox') + expect(in_viewport?(checkbox)).to eq true + end + + it 'scrolls from element by given amount with offset' do + driver.get('https://selenium.dev/selenium/web/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) + + driver.action.scroll_from(scroll_origin, 0, 200).perform + + iframe = driver.find_element(tag_name: 'iframe') + driver.switch_to.frame(iframe) + checkbox = driver.find_element(name: 'scroll_checkbox') + expect(in_viewport?(checkbox)).to eq true + end + + it 'scrolls by given amount with offset' do + driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html') + scroll_origin = WheelActions::ScrollOrigin.viewport(10, 10) + + driver.action.scroll_from(scroll_origin, 0, 200).perform + + iframe = driver.find_element(tag_name: 'iframe') + driver.switch_to.frame(iframe) + checkbox = driver.find_element(name: 'scroll_checkbox') + expect(in_viewport?(checkbox)).to eq true + end +end + +def in_viewport?(element) + in_viewport = <<~IN_VIEWPORT + for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight; + e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft; + return f + window.pageYOffset&&t+o>window.pageXOffset + IN_VIEWPORT + + driver.execute_script(in_viewport, element) +end From 73d3614f34d7f4faf107004bfb6d168aaaf542f6 Mon Sep 17 00:00:00 2001 From: titusfortner Date: Sun, 15 May 2022 18:41:38 -0500 Subject: [PATCH 2/2] update scroll wheel documentation --- website_and_docs/assets/scss/_badges.scss | 16 + website_and_docs/assets/scss/main.scss | 1 + .../webdriver/actions_api/wheel.en.md | 776 ++++-------------- .../layouts/shortcodes/gh-codeblock.html | 2 +- 4 files changed, 179 insertions(+), 616 deletions(-) create mode 100644 website_and_docs/assets/scss/_badges.scss diff --git a/website_and_docs/assets/scss/_badges.scss b/website_and_docs/assets/scss/_badges.scss new file mode 100644 index 000000000000..d9bd095b12c8 --- /dev/null +++ b/website_and_docs/assets/scss/_badges.scss @@ -0,0 +1,16 @@ + +.selenium-badge-version { + background:green; + color:white; + padding:.2rem; + font-weight:750; +} + +.selenium-badge-browser { + background:blue; + color:white; + padding:.2rem; + font-weight:750; +} + + diff --git a/website_and_docs/assets/scss/main.scss b/website_and_docs/assets/scss/main.scss index 730283578e87..aa552bacc612 100644 --- a/website_and_docs/assets/scss/main.scss +++ b/website_and_docs/assets/scss/main.scss @@ -2,6 +2,7 @@ @import "../../themes/docsy/assets/scss/main.scss"; @import "alerts"; @import "backgrounds"; +@import "badges"; @import "buttons"; @import "colors"; @import "images"; diff --git a/website_and_docs/content/documentation/webdriver/actions_api/wheel.en.md b/website_and_docs/content/documentation/webdriver/actions_api/wheel.en.md index 37f22a94bb44..9b75696cbdd1 100644 --- a/website_and_docs/content/documentation/webdriver/actions_api/wheel.en.md +++ b/website_and_docs/content/documentation/webdriver/actions_api/wheel.en.md @@ -6,632 +6,178 @@ description: > A representation of a scroll wheel input device for interacting with a web page. --- -## Scroll to element - -Scrolls to the element by scrolling the viewport. This way the element is at the bottom. - -{{< tabpane langEqualsHeader=true >}} - {{< tab header="Java" >}} -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.interactions.PointerInput; - -public class scrollToElement { - - public static void main(String[] args) { - WebDriver driver = new ChromeDriver(); - try { - driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html"); - WebElement element = driver.findElement(By.id("closepopup")); - - Actions actions = new Actions(driver); - actions.scroll(0, - 0, - 0, - 0, - PointerInput.Origin.fromElement(element)) - .perform(); - } finally { - driver.quit(); - } - } -} - {{< /tab >}} - {{< tab header="Python" >}} -from selenium import webdriver -from selenium.webdriver import ActionChains -from selenium.webdriver.common.by import By - -driver = webdriver.Chrome() -driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html") -element = driver.find_element(By.ID, "closepopup") - -ActionChains(driver).scroll(0, 0, 0, 0, origin=element).perform() - -driver.quit() - {{< /tab >}} - {{< tab header="CSharp" >}} - {{< /tab >}} - {{< tab header="Ruby" >}} -require 'selenium-webdriver' - -begin - driver = Selenium::WebDriver.for :chrome - driver.get 'https://crossbrowsertesting.github.io/selenium_example_page.html' - element = driver.find_element(:id, 'closepopup') - driver.action.scroll_to(element).perform -ensure - driver.quit -end - {{< /tab >}} - {{< tab header="JavaScript" >}} -const { Builder, By } = require('selenium-webdriver'); +

+ +Selenium v4.2

-(async function scrollToElement() { - let driver = await new Builder().forBrowser('chrome').build(); +

+Chromium

- try { - await driver.get('https://crossbrowsertesting.github.io/selenium_example_page.html'); - element = await driver.findElement(By.id('closepopup')); - await driver.actions().scroll(0, 0, 0, 0, element).perform(); - } - finally { - await driver.quit(); - } -})(); +There are 5 main scenarios for scrolling on a page. - {{< /tab >}} - {{< tab header="Kotlin" >}} -import org.openqa.selenium.By -import org.openqa.selenium.WebDriver -import org.openqa.selenium.chrome.ChromeDriver -import org.openqa.selenium.interactions.Actions -import org.openqa.selenium.interactions.PointerInput +## Scroll to element -fun main() { - val driver: WebDriver = ChromeDriver() - try { - driver["https://crossbrowsertesting.github.io/selenium_example_page.html"] - val element = driver.findElement(By.id("closepopup")) - val actions = Actions(driver) - actions.scroll( - 0, - 0, - 0, - 0, - PointerInput.Origin.fromElement(element) - ).perform() - } finally { - driver.quit() - } -} - {{< /tab >}} +This is the most common scenario. Unlike traditional click and send keys methods, +the actions class does not automatically scroll the target element into view, +so this method will need to be used if elements are not already inside the viewport. + +This method takes a web element as the sole argument. + +Regardless of whether the element is above or below the current viewscreen, +the viewport will be scrolled so the bottom of the element is at the bottom of the screen. + +{{< tabpane disableCodeBlock=true >}} + {{< tab header="Java" >}} + {{< gh-codeblock path="examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L37" >}} + {{< /tab >}} + {{< tab header="Python" >}} + {{< gh-codeblock path="examples/python/tests/actions_api/test_wheel.py#L12" >}} + {{< /tab >}} + {{< tab header="CSharp" >}} + {{< gh-codeblock path="examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs#L35" >}} + {{< /tab >}} + {{< tab header="Ruby" >}} + {{< gh-codeblock path="examples/ruby/spec/actions_api/wheel_spec.rb#L16" >}} + {{< /tab >}} + {{< tab header="JavaScript" >}} + Not implemented yet + {{< /tab >}} + {{< tab header="Kotlin" >}} + Not implemented yet + {{< /tab >}} {{< /tabpane >}} -## Scroll by given amount from element - -Scrolls to the element by scrolling the viewport. This way the element is at the bottom. -Scrolls the viewport further by the given amount i.e. horizontal and vertical offsets. - -{{< tabpane langEqualsHeader=true >}} - {{< tab header="Java" >}} -import org.openqa.selenium.By; -import org.openqa.selenium.Dimension; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.interactions.PointerInput; - -public class scrollByGivenAmountFromElement { - - public static void main(String[] args) throws Exception { - WebDriver driver = new ChromeDriver(); - try { - driver.manage().window().setSize(new Dimension(500, 400)); - driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html"); - WebElement element = driver.findElement(By.linkText("Go To Page 2")); - - Actions actions = new Actions(driver); - actions.scroll(0, - 0, - 0, - 300, - PointerInput.Origin.fromElement(element)) - .perform(); - } finally { - driver.quit(); - } - } -} - {{< /tab >}} - {{< tab header="Python" >}} -from selenium import webdriver -from selenium.webdriver import ActionChains -from selenium.webdriver.common.by import By - -driver = webdriver.Chrome() -driver.set_window_size(500, 400) -driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html") - -element = driver.find_element(By.LINK_TEXT, "Go To Page 2") - -ActionChains(driver).scroll(0, 0, 0, 300, origin=element).perform() - -driver.quit() - {{< /tab >}} - {{< tab header="CSharp" >}} - {{< /tab >}} - {{< tab header="Ruby" >}} -require 'selenium-webdriver' - -begin - driver = Selenium::WebDriver.for :chrome - target_size = Selenium::WebDriver::Dimension.new(500, 400) - driver.manage.window.size = target_size - driver.get 'https://crossbrowsertesting.github.io/selenium_example_page.html' - element = driver.find_element(:link_text, 'Go To Page 2') - driver.action.scroll_to(element, 0, 300).perform -ensure - driver.quit -end - {{< /tab >}} - {{< tab header="JavaScript" >}} -const { Builder, By } = require('selenium-webdriver'); - -(async function scollByGivenAmountFromElement() { - let driver = await new Builder().forBrowser('chrome').build(); - - try { - await driver.manage().window().setRect({ width: 500, height: 400 }); - await driver.get('https://crossbrowsertesting.github.io/selenium_example_page.html'); - element = await driver.findElement(By.linkText('Go To Page 2')); - - await driver.actions().scroll(0, 0, 0, 300, element).perform(); - } - finally { - await driver.quit(); - } -})(); - {{< /tab >}} - {{< tab header="Kotlin" >}} -import org.openqa.selenium.By -import org.openqa.selenium.Dimension -import org.openqa.selenium.WebDriver -import org.openqa.selenium.chrome.ChromeDriver -import org.openqa.selenium.interactions.Actions -import org.openqa.selenium.interactions.PointerInput - -fun main() { - val driver: WebDriver = ChromeDriver() - try { - driver.manage().window().size = Dimension(500, 400) - driver["https://crossbrowsertesting.github.io/selenium_example_page.html"] - val element = driver.findElement(By.linkText("Go To Page 2")) - val actions = Actions(driver) - actions.scroll( - 0, - 0, - 0, - 300, - PointerInput.Origin.fromElement(element) - ).perform() - } finally { - driver.quit() - } -} - {{< /tab >}} +## Scroll by given amount + +This is the second most common scenario for scrolling. Pass in an delta x and a delta y value for how much to scroll +in the right and down directions. Negative values represent left and up, respectively. + +{{< tabpane disableCodeBlock=true >}} + {{< tab header="Java" >}} + {{< gh-codeblock path="examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L48" >}} + {{< /tab >}} + {{< tab header="Python" >}} + {{< gh-codeblock path="examples/python/tests/actions_api/test_wheel.py#L22" >}} + {{< /tab >}} + {{< tab header="CSharp" >}} + {{< gh-codeblock path="examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs#L47" >}} + {{< /tab >}} + {{< tab header="Ruby" >}} + {{< gh-codeblock path="examples/ruby/spec/actions_api/wheel_spec.rb#L26" >}} + {{< /tab >}} + {{< tab header="JavaScript" >}} + Not implemented yet + {{< /tab >}} + {{< tab header="Kotlin" >}} + Not implemented yet + {{< /tab >}} {{< /tabpane >}} -## Scroll by given amount - -Scrolls the viewport by the given amount i.e. horizontal and vertical offsets. - -{{< tabpane langEqualsHeader=true >}} - {{< tab header="Java" >}} -import org.openqa.selenium.Dimension; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.interactions.PointerInput; - -public class scrollByGivenAmountFromViewPort { - - public static void main(String[] args) throws Exception { - WebDriver driver = new ChromeDriver(); - try { - driver.manage().window().setSize(new Dimension(500, 400)); - driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html"); - - Actions actions = new Actions(driver); - actions.scroll(0, - 0, - 0, - 200, - PointerInput.Origin.viewport()) - .perform(); - } finally { - driver.quit(); - } - } -} - {{< /tab >}} - {{< tab header="Python" >}} -from selenium import webdriver -from selenium.webdriver import ActionChains - -driver = webdriver.Chrome() -driver.set_window_size(500, 400) -driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html") - -ActionChains(driver).scroll(0, 0, 0, 200).perform() - -driver.quit() - {{< /tab >}} - {{< tab header="CSharp" >}} - {{< /tab >}} - {{< tab header="Ruby" >}} -require 'selenium-webdriver' - -begin - driver = Selenium::WebDriver.for :chrome - target_size = Selenium::WebDriver::Dimension.new(500, 400) - driver.manage.window.size = target_size - driver.get 'https://crossbrowsertesting.github.io/selenium_example_page.html' - - driver.action.scroll_by(0, 200).perform -ensure - driver.quit -end - {{< /tab >}} - {{< tab header="JavaScript" >}} -const { Origin } = require('selenium-webdriver'); -const { Builder } = require('selenium-webdriver'); - -(async function scollByGivenAmountFromViewport() { - let driver = await new Builder().forBrowser('chrome').build(); - - try { - await driver.manage().window().setRect({ width: 500, height: 400 }); - await driver.get('https://crossbrowsertesting.github.io/selenium_example_page.html'); - - await driver.actions().scroll(0, 0, 0, 200, Origin.VIEWPORT).perform(); - } - finally { - await driver.quit(); - } -})(); - {{< /tab >}} - {{< tab header="Kotlin" >}} -import org.openqa.selenium.Dimension -import org.openqa.selenium.WebDriver -import org.openqa.selenium.chrome.ChromeDriver -import org.openqa.selenium.interactions.Actions -import org.openqa.selenium.interactions.PointerInput - -fun main() { - val driver: WebDriver = ChromeDriver() - try { - driver.manage().window().size = Dimension(500, 400) - driver["https://crossbrowsertesting.github.io/selenium_example_page.html"] - val actions = Actions(driver) - actions.scroll( - 0, - 0, - 0, - 200, - PointerInput.Origin.viewport() - ).perform() - } finally { - driver.quit() - } -} - {{< /tab >}} +## Scroll from an element by a given amount + +This scenario is effectively a combination of the above two methods. + +To execute this use the "Scroll From" method, which takes 3 arguments. +The first represents the origination point, which we designate as the element, +and the second two are the delta x and delta y values. + +If the element is out of the viewport, +it will be scrolled to the bottom of the screen, then the page will be scrolled by the provided +delta x and delta y values. + +{{< tabpane disableCodeBlock=true >}} + {{< tab header="Java" >}} + {{< gh-codeblock path="examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L59" >}} + {{< /tab >}} + {{< tab header="Python" >}} + {{< gh-codeblock path="examples/python/tests/actions_api/test_wheel.py#L30-L32" >}} + {{< /tab >}} + {{< tab header="CSharp" >}} + {{< gh-codeblock path="examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs#L57-L62" >}} + {{< /tab >}} + {{< tab header="Ruby" >}} + {{< gh-codeblock path="examples/ruby/spec/actions_api/wheel_spec.rb#L34-L36" >}} + {{< /tab >}} + {{< tab header="JavaScript" >}} + Not implemented yet + {{< /tab >}} + {{< tab header="Kotlin" >}} + Not implemented yet + {{< /tab >}} {{< /tabpane >}} -## Scroll from a offset of origin (viewport) by given amount - -The origin is the where the cursor is placed before the scroll is executed. -For example, the position on the screen where the cursor is before scrolling a mouse wheel. -For origin as viewport, the origin offset is calculated from the upper left corner of the viewport. -Starting from this origin, the viewport is scrolled by the given amount -i.e. horizontal and vertical offsets. - -{{< tabpane langEqualsHeader=true >}} - {{< tab header="Java" >}} -import org.openqa.selenium.By; -import org.openqa.selenium.Dimension; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.interactions.PointerInput; - -public class scrollFromOffsetOfOriginViewportByGivenAmount { - - public static void main(String[] args) throws Exception { - WebDriver driver = new ChromeDriver(); - try { - driver.manage().window().setSize(new Dimension(600, 600)); - driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html"); - WebElement textarea = driver.findElement(By.name("textarea")); - - Actions actions = new Actions(driver); - - textarea.sendKeys( - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); - - actions.scroll(20, - 200, - 0, - -50, - PointerInput.Origin.viewport()) - .perform(); - } finally { - driver.quit(); - } - } -} - {{< /tab >}} - {{< tab header="Python" >}} -from selenium import webdriver -from selenium.webdriver import ActionChains -from selenium.webdriver.common.by import By - -driver = webdriver.Chrome() -driver.set_window_size(600, 600) -driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html") - -textarea = driver.find_element(By.NAME, "textarea") - -textarea.send_keys("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") - -ActionChains(driver).scroll(20, 200, 0, -50).perform() - -driver.quit() - {{< /tab >}} - {{< tab header="CSharp" >}} - {{< /tab >}} - {{< tab header="Ruby" >}} -require 'selenium-webdriver' - -begin - driver = Selenium::WebDriver.for :chrome - target_size = Selenium::WebDriver::Dimension.new(600, 600) - driver.manage.window.size = target_size - driver.get 'https://crossbrowsertesting.github.io/selenium_example_page.html' - textarea = driver.find_element(:name, 'textarea') - - textarea.send_keys 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + - 'cccccccccccccccccccccccccccccccc' + - 'dddddddddddddddddddddddddddddddd' + - 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' - - origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(20, 200) - driver.action.scroll(0, -50, origin: origin).perform -ensure - driver.quit -end - {{< /tab >}} - {{< tab header="JavaScript" >}} -const { Origin } = require('selenium-webdriver'); -const { Builder, By } = require('selenium-webdriver'); - -(async function scollByGivenAmountFromElement() { - let driver = await new Builder().forBrowser('chrome').build(); - - try { - await driver.manage().window().setRect({ width: 600, height: 600 }); - await driver.get('https://crossbrowsertesting.github.io/selenium_example_page.html'); - textarea = await driver.findElement(By.name('textarea')); - - await textarea.sendKeys('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + - 'cccccccccccccccccccccccccccccccc' + - 'dddddddddddddddddddddddddddddddd' + - 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'); - - await driver.actions().scroll(20, 200, 0, -50, Origin.VIEWPORT).perform(); - } - finally { - await driver.quit(); - } -})(); - {{< /tab >}} - {{< tab header="Kotlin" >}} -import org.openqa.selenium.By -import org.openqa.selenium.Dimension -import org.openqa.selenium.WebDriver -import org.openqa.selenium.chrome.ChromeDriver -import org.openqa.selenium.interactions.Actions -import org.openqa.selenium.interactions.PointerInput - -fun main() { - val driver: WebDriver = ChromeDriver() - try { - driver.manage().window().size = Dimension(600, 600) - driver["https://crossbrowsertesting.github.io/selenium_example_page.html"] - val textarea = driver.findElement(By.name("textarea")) - val actions = Actions(driver) - textarea.sendKeys( - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - ) - actions.scroll( - 20, - 200, - 0, - -50, - PointerInput.Origin.viewport() - ).perform() - } finally { - driver.quit() - } -} - {{< /tab >}} +## Scroll from an element with an offset + +This scenario is used when you need to scroll only a portion of the screen, and it is outside the viewport. +Or is inside the viewport and the portion of the screen that must be scrolled +is a known offset away from a specific element. + +This uses the "Scroll From" method again, and in addition to specifying the element, +an offset is specified to indicate the origin point of the scroll. The offset is +calculated from the center of the provided element. + +If the element is out of the viewport, +it first will be scrolled to the bottom of the screen, then the origin of the scroll will be determined +by adding the offset to the coordinates of the center of the element, and finally +the page will be scrolled by the provided delta x and delta y values. + +Note that if the offset from the center of the element falls outside of the viewport, +it will result in an exception. + +{{< tabpane disableCodeBlock=true >}} + {{< tab header="Java" >}} + {{< gh-codeblock path="examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L70-L72" >}} + {{< /tab >}} + {{< tab header="Python" >}} + {{< gh-codeblock path="examples/python/tests/actions_api/test_wheel.py#L42-L44" >}} + {{< /tab >}} + {{< tab header="CSharp" >}} + {{< gh-codeblock path="examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs#L74-L81" >}} + {{< /tab >}} + {{< tab header="Ruby" >}} + {{< gh-codeblock path="examples/ruby/spec/actions_api/wheel_spec.rb#L46-L48" >}} + {{< /tab >}} + {{< tab header="JavaScript" >}} + Not implemented yet + {{< /tab >}} + {{< tab header="Kotlin" >}} + Not implemented yet + {{< /tab >}} {{< /tabpane >}} ## Scroll from a offset of origin (element) by given amount -The origin is the where the cursor is placed before the scroll is executed. -For example, the position on the screen where the cursor is before scrolling a mouse wheel. -For origin as element, the origin offset is calculated from the center of the element. -Starting from this origin, the viewport is scrolled by the given amount -i.e. horizontal and vertical offsets. - -{{< tabpane langEqualsHeader=true >}} - {{< tab header="Java" >}} -import org.openqa.selenium.By; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.interactions.PointerInput; - -public class scrollFromOffsetOfOriginElementByGivenAmount { - - public static void main(String[] args) throws Exception { - WebDriver driver = new ChromeDriver(); - try { - driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html"); - WebElement textarea = driver.findElement(By.name("textarea")); - WebElement submit = driver.findElement(By.id("submitbtn")); - - Actions actions = new Actions(driver); - - textarea.sendKeys( - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); - - actions.scroll(0, - -50, - 0, - -50, - PointerInput.Origin.fromElement(submit)) - .perform(); - } finally { - driver.quit(); - } - } -} - {{< /tab >}} - {{< tab header="Python" >}} -from selenium import webdriver -from selenium.webdriver import ActionChains -from selenium.webdriver.common.by import By - -driver = webdriver.Chrome() -driver.get("https://crossbrowsertesting.github.io/selenium_example_page.html") - -textarea = driver.find_element(By.NAME, "textarea") -submit = driver.find_element(By.ID, "submitbtn") - -textarea.send_keys("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") - -ActionChains(driver).scroll(0, -50, 0, -50, origin=submit).perform() - -driver.quit() - {{< /tab >}} - {{< tab header="CSharp" >}} - {{< /tab >}} - {{< tab header="Ruby" >}} -require 'selenium-webdriver' - -begin - driver = Selenium::WebDriver.for :chrome - driver.get 'https://crossbrowsertesting.github.io/selenium_example_page.html' - textarea = driver.find_element(:name, 'textarea') - submit = driver.find_element(:id, 'submitbtn') - - textarea.send_keys 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + - 'cccccccccccccccccccccccccccccccc' + - 'dddddddddddddddddddddddddddddddd' + - 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' - - origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(submit, 0, -50) - driver.action.scroll(0, -50, origin: origin).perform -ensure - driver.quit -end - {{< /tab >}} - {{< tab header="JavaScript" >}} -const { Builder, By } = require('selenium-webdriver'); - -(async function scollByGivenAmountFromElement() { - let driver = await new Builder().forBrowser('chrome').build(); - - try { - await driver.get('https://crossbrowsertesting.github.io/selenium_example_page.html'); - textarea = await driver.findElement(By.name('textarea')); - submit = await driver.findElement(By.id('submitbtn')); - - await textarea.sendKeys('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + - 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' + - 'cccccccccccccccccccccccccccccccc' + - 'dddddddddddddddddddddddddddddddd' + - 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'); - - await driver.actions().scroll(0, -50, 0, -50, submit).perform(); - } - finally { - await driver.quit(); - } -})(); - {{< /tab >}} - {{< tab header="Kotlin" >}} -import org.openqa.selenium.By -import org.openqa.selenium.WebDriver -import org.openqa.selenium.chrome.ChromeDriver -import org.openqa.selenium.interactions.Actions -import org.openqa.selenium.interactions.PointerInput - -fun main() { - val driver: WebDriver = ChromeDriver() - try { - driver["https://crossbrowsertesting.github.io/selenium_example_page.html"] - val textarea = driver.findElement(By.name("textarea")) - val submit = driver.findElement(By.id("submitbtn")) - val actions = Actions(driver) - textarea.sendKeys( - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + - "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + - "cccccccccccccccccccccccccccccccc" + - "dddddddddddddddddddddddddddddddd" + - "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - ) - actions.scroll( - 0, - -50, - 0, - -50, - PointerInput.Origin.fromElement(submit) - ).perform() - } finally { - driver.quit() - } -} - {{< /tab >}} -{{< /tabpane >}} \ No newline at end of file +The final scenario is used when you need to scroll only a portion of the screen, +and it is already inside the viewport. + +This uses the "Scroll From" method again, but the viewport is designated instead +of an element. An offset is specified from the upper left corner of the +current viewport. After the origin point is determined, +the page will be scrolled by the provided delta x and delta y values. + +Note that if the offset from the upper left corner of the viewport falls outside of the screen, +it will result in an exception. + +{{< tabpane disableCodeBlock=true >}} + {{< tab header="Java" >}} + {{< gh-codeblock path="examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L83-L85" >}} + {{< /tab >}} + {{< tab header="Python" >}} + {{< gh-codeblock path="examples/python/tests/actions_api/test_wheel.py#L54-L56" >}} + {{< /tab >}} + {{< tab header="CSharp" >}} + {{< gh-codeblock path="examples/dotnet/SeleniumDocs/ActionsApi/WheelTest.cs#L93-L100" >}} + {{< /tab >}} + {{< tab header="Ruby" >}} + {{< gh-codeblock path="examples/ruby/spec/actions_api/wheel_spec.rb#L58-L60" >}} + {{< /tab >}} + {{< tab header="JavaScript" >}} + Not implemented yet + {{< /tab >}} + {{< tab header="Kotlin" >}} + Not implemented yet + {{< /tab >}} +{{< /tabpane >}} diff --git a/website_and_docs/layouts/shortcodes/gh-codeblock.html b/website_and_docs/layouts/shortcodes/gh-codeblock.html index 514b3654d6cf..2377071887b0 100644 --- a/website_and_docs/layouts/shortcodes/gh-codeblock.html +++ b/website_and_docs/layouts/shortcodes/gh-codeblock.html @@ -2,7 +2,7 @@ {{ $webBaseUrl := .Get "webBaseUrl" | default "https://github.com" }} {{ $org := .Get "org" | default "SeleniumHQ" }} {{ $repo := .Get "repo" | default "seleniumhq.github.io" }} -{{ $branch := .Get "branch" | default "trunk" }} +{{ $branch := .Get "branch" | default "wheel_examples" }} {{ $fullPath := .Get "path" }} {{ $path := index (split $fullPath "#") 0 }}