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

org.openqa.selenium.remote.RemoteWebElement Maven / Gradle / Ivy

Go to download

Selenium automates browsers. That's it! What you do with that power is entirely up to you.

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.remote;

import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.Beta;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WrapsDriver;
import org.openqa.selenium.WrapsElement;
import org.openqa.selenium.interactions.Coordinates;
import org.openqa.selenium.interactions.Locatable;
import org.openqa.selenium.internal.FindsByClassName;
import org.openqa.selenium.internal.FindsByCssSelector;
import org.openqa.selenium.internal.FindsById;
import org.openqa.selenium.internal.FindsByLinkText;
import org.openqa.selenium.internal.FindsByName;
import org.openqa.selenium.internal.FindsByTagName;
import org.openqa.selenium.internal.FindsByXPath;
import org.openqa.selenium.io.Zip;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class RemoteWebElement implements WebElement, FindsByLinkText, FindsById, FindsByName,
                                         FindsByTagName, FindsByClassName, FindsByCssSelector,
                                         FindsByXPath, WrapsDriver, TakesScreenshot, Locatable {
  private String foundBy;
  protected String id;
  protected RemoteWebDriver parent;
  protected FileDetector fileDetector;

  protected void setFoundBy(SearchContext foundFrom, String locator, String term) {
    this.foundBy = String.format("[%s] -> %s: %s", foundFrom, locator, term);
  }

  public void setParent(RemoteWebDriver parent) {
    this.parent = parent;
  }

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public void setFileDetector(FileDetector detector) {
    fileDetector = detector;
  }

  @Override
  public void click() {
    execute(DriverCommand.CLICK_ELEMENT(id));
  }

  @Override
  public void submit() {
    execute(DriverCommand.SUBMIT_ELEMENT(id));
  }

  @Override
  public void sendKeys(CharSequence... keysToSend) {
    if (keysToSend == null || keysToSend.length == 0) {
      throw new IllegalArgumentException("Keys to send should be a not null CharSequence");
    }
    for (CharSequence cs : keysToSend) {
      if (cs == null) {
        throw new IllegalArgumentException("Keys to send should be a not null CharSequence");
      }
    }

    String allKeysToSend = String.join("", keysToSend);

    List files = Arrays.stream(allKeysToSend.split("\n"))
        .map(fileDetector::getLocalFile)
        .collect(Collectors.toList());
    if (! files.contains(null)) {
      allKeysToSend = files.stream()
          .map(this::upload)
          .collect(Collectors.joining("\n"));
    }

    execute(DriverCommand.SEND_KEYS_TO_ELEMENT(id, new CharSequence[]{allKeysToSend}));
  }

  private String upload(File localFile) {
    if (!localFile.isFile()) {
      throw new WebDriverException("You may only upload files: " + localFile);
    }

    try {
      String zip = Zip.zip(localFile);
      Response response = execute(DriverCommand.UPLOAD_FILE(zip));
      return (String) response.getValue();
    } catch (IOException e) {
      throw new WebDriverException("Cannot upload " + localFile, e);
    }
  }

  @Override
  public void clear() {
    execute(DriverCommand.CLEAR_ELEMENT(id));
  }

  @Override
  public String getTagName() {
    return (String) execute(DriverCommand.GET_ELEMENT_TAG_NAME(id))
        .getValue();
  }

  @Override
  public String getAttribute(String name) {
    return stringValueOf(
        execute(DriverCommand.GET_ELEMENT_ATTRIBUTE(id, name))
        .getValue());
  }

  private static String stringValueOf(Object o) {
    if (o == null) {
      return null;
    }
    return String.valueOf(o);
  }

  @Override
  public boolean isSelected() {
    Object value = execute(DriverCommand.IS_ELEMENT_SELECTED(id))
        .getValue();
    try {
      return (Boolean) value;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to Boolean: " + value, ex);
    }
  }

  @Override
  public boolean isEnabled() {
    Object value = execute(DriverCommand.IS_ELEMENT_ENABLED(id))
        .getValue();
    try {
      return (Boolean) value;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to Boolean: " + value, ex);
    }
  }

  @Override
  public String getText() {
    Response response = execute(DriverCommand.GET_ELEMENT_TEXT(id));
    return (String) response.getValue();
  }

  @Override
  public String getCssValue(String propertyName) {
    Response response = execute(DriverCommand.GET_ELEMENT_VALUE_OF_CSS_PROPERTY(id, propertyName));
    return (String) response.getValue();
  }

  @Override
  public List findElements(By by) {
    return by.findElements(this);
  }

  @Override
  public WebElement findElement(By by) {
    return by.findElement(this);
  }

  protected WebElement findElement(String using, String value) {
    Response response = execute(DriverCommand.FIND_CHILD_ELEMENT(id, using, value));

    Object responseValue = response.getValue();
    if (responseValue == null) { // see https://github.com/SeleniumHQ/selenium/issues/5809
      throw new NoSuchElementException(String.format("Cannot locate an element using %s=%s", using, value));
    }
    WebElement element;
    try {
      element = (WebElement) responseValue;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to WebElement: " + value, ex);
    }
    parent.setFoundBy(this, element, using, value);
    return element;
  }

  @SuppressWarnings("unchecked")
  protected List findElements(String using, String value) {
    Response response = execute(DriverCommand.FIND_CHILD_ELEMENTS(id, using, value));
    Object responseValue = response.getValue();
    if (responseValue == null) { // see https://github.com/SeleniumHQ/selenium/issues/4555
      return Collections.emptyList();
    }
    List allElements;
    try {
      allElements = (List) responseValue;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to List: " + responseValue, ex);
    }
    allElements.forEach(element -> parent.setFoundBy(this, element, using, value));
    return allElements;
  }

  @Override
  public WebElement findElementById(String using) {
    return findElement("id", using);
  }

  @Override
  public List findElementsById(String using) {
    return findElements("id", using);
  }

  @Override
  public WebElement findElementByLinkText(String using) {
    return findElement("link text", using);
  }

  @Override
  public List findElementsByLinkText(String using) {
    return findElements("link text", using);
  }

  @Override
  public WebElement findElementByName(String using) {
    return findElement("name", using);
  }

  @Override
  public List findElementsByName(String using) {
    return findElements("name", using);
  }

  @Override
  public WebElement findElementByClassName(String using) {
    return findElement("class name", using);
  }

  @Override
  public List findElementsByClassName(String using) {
    return findElements("class name", using);
  }

  @Override
  public WebElement findElementByCssSelector(String using) {
    return findElement("css selector", using);
  }

  @Override
  public List findElementsByCssSelector(String using) {
    return findElements("css selector", using);
  }

  @Override
  public WebElement findElementByXPath(String using) {
    return findElement("xpath", using);
  }

  @Override
  public List findElementsByXPath(String using) {
    return findElements("xpath", using);
  }

  @Override
  public WebElement findElementByPartialLinkText(String using) {
    return findElement("partial link text", using);
  }

  @Override
  public List findElementsByPartialLinkText(String using) {
    return findElements("partial link text", using);
  }

  @Override
  public WebElement findElementByTagName(String using) {
    return findElement("tag name", using);
  }

  @Override
  public List findElementsByTagName(String using) {
    return findElements("tag name", using);
  }

  Response execute(CommandPayload payload) {
    return parent.execute(payload);
  }

  protected Response execute(String command, Map parameters) {
    return parent.execute(command, parameters);
  }

  @Override
  public boolean equals(Object obj) {
    if (!(obj instanceof WebElement)) {
      return false;
    }

    WebElement other = (WebElement) obj;
    while (other instanceof WrapsElement) {
      other = ((WrapsElement) other).getWrappedElement();
    }

    if (!(other instanceof RemoteWebElement)) {
      return false;
    }

    RemoteWebElement otherRemoteWebElement = (RemoteWebElement) other;

    return id.equals(otherRemoteWebElement.id);
  }

  /**
   * @return This element's hash code, which is a hash of its internal opaque ID.
   */
  @Override
  public int hashCode() {
    return id.hashCode();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.openqa.selenium.internal.WrapsDriver#getWrappedDriver()
   */
  @Override
  public WebDriver getWrappedDriver() {
    return parent;
  }

  @Override
  public boolean isDisplayed() {
    Object value = execute(DriverCommand.IS_ELEMENT_DISPLAYED(id))
        .getValue();
    try {
      return (Boolean) value;
    } catch (ClassCastException ex) {
      throw new WebDriverException("Returned value cannot be converted to Boolean: " + value, ex);
    }
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public Point getLocation() {
    Response response = execute(DriverCommand.GET_ELEMENT_LOCATION(id));
    Map rawPoint = (Map) response.getValue();
    int x = ((Number) rawPoint.get("x")).intValue();
    int y = ((Number) rawPoint.get("y")).intValue();
    return new Point(x, y);
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public Dimension getSize() {
    Response response = execute(DriverCommand.GET_ELEMENT_SIZE(id));
    Map rawSize = (Map) response.getValue();
    int width = ((Number) rawSize.get("width")).intValue();
    int height = ((Number) rawSize.get("height")).intValue();
    return new Dimension(width, height);
  }

  @Override
  @SuppressWarnings({"unchecked"})
  public Rectangle getRect() {
    Response response = execute(DriverCommand.GET_ELEMENT_RECT(id));
    Map rawRect = (Map) response.getValue();
    int x = ((Number) rawRect.get("x")).intValue();
    int y = ((Number) rawRect.get("y")).intValue();
    int width = ((Number) rawRect.get("width")).intValue();
    int height = ((Number) rawRect.get("height")).intValue();
    return new Rectangle(x, y, height, width);
  }

  @Override
  public Coordinates getCoordinates() {
    return new Coordinates() {

      @Override
      public Point onScreen() {
        throw new UnsupportedOperationException("Not supported yet.");
      }

      @Override
      public Point inViewPort() {
        Response response = execute(DriverCommand.GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW(getId()));

        @SuppressWarnings("unchecked")
        Map mapped = (Map) response.getValue();
        return new Point(mapped.get("x").intValue(), mapped.get("y").intValue());
      }

      @Override
      public Point onPage() {
        return getLocation();
      }

      @Override
      public Object getAuxiliary() {
        return getId();
      }
    };
  }

  @Override
  @Beta
  public  X getScreenshotAs(OutputType outputType) throws WebDriverException {
    Response response = execute(DriverCommand.ELEMENT_SCREENSHOT(id));
    Object result = response.getValue();
    if (result instanceof String) {
      String base64EncodedPng = (String) result;
      return outputType.convertFromBase64Png(base64EncodedPng);
    } else if (result instanceof byte[]) {
      String base64EncodedPng = new String((byte[]) result);
      return outputType.convertFromBase64Png(base64EncodedPng);
    } else {
      throw new RuntimeException(String.format("Unexpected result for %s command: %s",
                                               DriverCommand.ELEMENT_SCREENSHOT,
                                               result == null ? "null" : result.getClass().getName() + " instance"));
    }
  }

  public String toString() {
    if (foundBy == null) {
      return String.format("[%s -> unknown locator]", super.toString());
    }
    return String.format("[%s]", foundBy);
  }

  public Map toJson() {
    return ImmutableMap.of(
        Dialect.OSS.getEncodedElementKey(), getId(),
        Dialect.W3C.getEncodedElementKey(), getId());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy