All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openqa.selenium.interactions.Actions Maven / Gradle / Ivy

There is a newer version: 4.19.1
Show newest version
// 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.

package org.openqa.selenium.interactions;

import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.internal.Locatable;

/**
 * The user-facing API for emulating complex user gestures. Use this class rather than using the
 * Keyboard or Mouse directly.
 *
 * Implements the builder pattern: Builds a CompositeAction containing all actions specified by the
 * method calls.
 */
public class Actions {
  protected WebDriver driver;
  protected Mouse mouse;
  protected Keyboard keyboard;
  protected CompositeAction action;

  /**
   * Default constructor - uses the default keyboard, mouse implemented by the driver.
   * @param driver the driver providing the implementations to use.
   */
  public Actions(WebDriver driver) {
    this.driver = driver;
    this.mouse = ((HasInputDevices) driver).getMouse();
    this.keyboard = ((HasInputDevices) driver).getKeyboard();
    resetCompositeAction();
  }

  /**
   * A constructor that should only be used when the keyboard or mouse were extended to provide
   * additional functionality (for example, dragging-and-dropping from the desktop).
   * @param keyboard the {@link Keyboard} implementation to delegate to.
   * @param mouse the {@link Mouse} implementation to delegate to.
   */
  public Actions(Keyboard keyboard, Mouse mouse) {
    this.mouse = mouse;
    this.keyboard = keyboard;
    resetCompositeAction();
  }

  /**
   * Only used by the TouchActions class.
   * @param keyboard implementation to delegate to.
   */
  public Actions(Keyboard keyboard) {
    this.keyboard = keyboard;
    resetCompositeAction();
  }

  private void resetCompositeAction() {
    action = new CompositeAction(driver);
  }

  /**
   * Performs a modifier key press. Does not release the modifier key - subsequent interactions
   * may assume it's kept pressed.
   * Note that the modifier key is never released implicitly - either
   * keyUp(theKey) or sendKeys(Keys.NULL)
   * must be called to release the modifier.
   * @param theKey Either {@link Keys#SHIFT}, {@link Keys#ALT} or {@link Keys#CONTROL}. If the
   * provided key is none of those, {@link IllegalArgumentException} is thrown.
   * @return A self reference.
   */
  public Actions keyDown(Keys theKey) {
    return this.keyDown(null, theKey);
  }

  /**
   * Performs a modifier key press after focusing on an element. Equivalent to:
   * Actions.click(element).sendKeys(theKey);
   * @see #keyDown(org.openqa.selenium.Keys)
   *
   * @param theKey Either {@link Keys#SHIFT}, {@link Keys#ALT} or {@link Keys#CONTROL}. If the
   * provided key is none of those, {@link IllegalArgumentException} is thrown.
   * @param element WebElement to perform the action
   * @return A self reference.
   */
  public Actions keyDown(WebElement element, Keys theKey) {
    action.addAction(new KeyDownAction(keyboard, mouse, (Locatable) element, theKey));
    return this;
  }

  /**
   * Performs a modifier key release. Releasing a non-depressed modifier key will yield undefined
   * behaviour.
   *
   * @param theKey Either {@link Keys#SHIFT}, {@link Keys#ALT} or {@link Keys#CONTROL}.
   * @return A self reference.
   */
  public Actions keyUp(Keys theKey) {
    return this.keyUp(null, theKey);
  }

  /**
   * Performs a modifier key release after focusing on an element. Equivalent to:
   * Actions.click(element).sendKeys(theKey);
   * @see #keyUp(org.openqa.selenium.Keys) on behaviour regarding non-depressed modifier keys.
   *
   * @param theKey Either {@link Keys#SHIFT}, {@link Keys#ALT} or {@link Keys#CONTROL}.
   * @param element WebElement to perform the action on
   * @return A self reference.
   */
  public Actions keyUp(WebElement element, Keys theKey) {
    action.addAction(new KeyUpAction(keyboard, mouse, (Locatable) element, theKey));
    return this;
  }

  /**
   * Sends keys to the active element. This differs from calling
   * {@link WebElement#sendKeys(CharSequence...)} on the active element in two ways:
   * 
    *
  • The modifier keys included in this call are not released.
  • *
  • There is no attempt to re-focus the element - so sendKeys(Keys.TAB) for switching * elements should work.
  • *
* * @see WebElement#sendKeys(CharSequence...) * * @param keysToSend The keys. * @return A self reference. */ public Actions sendKeys(CharSequence... keysToSend) { return this.sendKeys(null, keysToSend); } /** * Equivalent to calling: * Actions.click(element).sendKeys(keysToSend). * This method is different from {@link org.openqa.selenium.WebElement#sendKeys(CharSequence...)} - see * {@link Actions#sendKeys(CharSequence...)} for details how. * * @see #sendKeys(java.lang.CharSequence[]) * * @param element element to focus on. * @param keysToSend The keys. * @return A self reference. */ public Actions sendKeys(WebElement element, CharSequence... keysToSend) { action.addAction(new SendKeysAction(keyboard, mouse, (Locatable) element, keysToSend)); return this; } /** * Clicks (without releasing) in the middle of the given element. This is equivalent to: * Actions.moveToElement(onElement).clickAndHold() * * @param onElement Element to move to and click. * @return A self reference. */ public Actions clickAndHold(WebElement onElement) { action.addAction(new ClickAndHoldAction(mouse, (Locatable) onElement)); return this; } /** * Clicks (without releasing) at the current mouse location. * @return A self reference. */ public Actions clickAndHold() { return this.clickAndHold(null); } /** * Releases the depressed left mouse button, in the middle of the given element. * This is equivalent to: * Actions.moveToElement(onElement).release() * * Invoking this action without invoking {@link #clickAndHold()} first will result in * undefined behaviour. * * @param onElement Element to release the mouse button above. * @return A self reference. */ public Actions release(WebElement onElement) { action.addAction(new ButtonReleaseAction(mouse, (Locatable) onElement)); return this; } /** * Releases the depressed left mouse button at the current mouse location. * @see #release(org.openqa.selenium.WebElement) * @return A self reference. */ public Actions release() { return this.release(null); } /** * Clicks in the middle of the given element. Equivalent to: * Actions.moveToElement(onElement).click() * * @param onElement Element to click. * @return A self reference. */ public Actions click(WebElement onElement) { action.addAction(new ClickAction(mouse, (Locatable) onElement)); return this; } /** * Clicks at the current mouse location. Useful when combined with * {@link #moveToElement(org.openqa.selenium.WebElement, int, int)} or * {@link #moveByOffset(int, int)}. * @return A self reference. */ public Actions click() { return this.click(null); } /** * Performs a double-click at middle of the given element. Equivalent to: * Actions.moveToElement(element).doubleClick() * * @param onElement Element to move to. * @return A self reference. */ public Actions doubleClick(WebElement onElement) { action.addAction(new DoubleClickAction(mouse, (Locatable) onElement)); return this; } /** * Performs a double-click at the current mouse location. * @return A self reference. */ public Actions doubleClick() { return this.doubleClick(null); } /** * Moves the mouse to the middle of the element. The element is scrolled into view and its * location is calculated using getBoundingClientRect. * @param toElement element to move to. * @return A self reference. */ public Actions moveToElement(WebElement toElement) { action.addAction(new MoveMouseAction(mouse, (Locatable) toElement)); return this; } /** * Moves the mouse to an offset from the top-left corner of the element. * The element is scrolled into view and its location is calculated using getBoundingClientRect. * @param toElement element to move to. * @param xOffset Offset from the top-left corner. A negative value means coordinates left from * the element. * @param yOffset Offset from the top-left corner. A negative value means coordinates above * the element. * @return A self reference. */ public Actions moveToElement(WebElement toElement, int xOffset, int yOffset) { action.addAction(new MoveToOffsetAction(mouse, (Locatable) toElement, xOffset, yOffset)); return this; } /** * Moves the mouse from its current position (or 0,0) by the given offset. If the coordinates * provided are outside the viewport (the mouse will end up outside the browser window) then * the viewport is scrolled to match. * @param xOffset horizontal offset. A negative value means moving the mouse left. * @param yOffset vertical offset. A negative value means moving the mouse up. * @return A self reference. * @throws MoveTargetOutOfBoundsException if the provided offset is outside the document's * boundaries. */ public Actions moveByOffset(int xOffset, int yOffset) { action.addAction(new MoveToOffsetAction(mouse, null, xOffset, yOffset)); return this; } /** * Performs a context-click at middle of the given element. First performs a mouseMove * to the location of the element. * * @param onElement Element to move to. * @return A self reference. */ public Actions contextClick(WebElement onElement) { action.addAction(new ContextClickAction(mouse, (Locatable) onElement)); return this; } /** * Performs a context-click at the current mouse location. * @return A self reference. */ public Actions contextClick() { return this.contextClick(null); } /** * A convenience method that performs click-and-hold at the location of the source element, * moves to the location of the target element, then releases the mouse. * * @param source element to emulate button down at. * @param target element to move to and release the mouse at. * @return A self reference. */ public Actions dragAndDrop(WebElement source, WebElement target) { action.addAction(new ClickAndHoldAction(mouse, (Locatable) source)); action.addAction(new MoveMouseAction(mouse, (Locatable) target)); action.addAction(new ButtonReleaseAction(mouse, (Locatable) target)); return this; } /** * A convenience method that performs click-and-hold at the location of the source element, * moves by a given offset, then releases the mouse. * * @param source element to emulate button down at. * @param xOffset horizontal move offset. * @param yOffset vertical move offset. * @return A self reference. */ public Actions dragAndDropBy(WebElement source, int xOffset, int yOffset) { action.addAction(new ClickAndHoldAction(mouse, (Locatable) source)); action.addAction(new MoveToOffsetAction(mouse, null, xOffset, yOffset)); action.addAction(new ButtonReleaseAction(mouse, null)); return this; } /** * Performs a pause. * * @param pause pause duration, in milliseconds. * @return A self reference. * * @deprecated 'Pause' is considered to be a bad design practice. */ @Deprecated public Actions pause(long pause) { action.addAction(new PauseAction(pause)); return this; } /** * Generates a composite action containing all actions so far, ready to be performed (and * resets the internal builder state, so subsequent calls to build() will contain fresh * sequences). * * @return the composite action */ public Action build() { CompositeAction toReturn = action; resetCompositeAction(); return toReturn; } /** * A convenience method for performing the actions without calling build() first. */ public void perform() { build().perform(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy