org.openqa.selenium.remote.RemoteWebElement.java Source code

Java tutorial

Introduction

Here is the source code for org.openqa.selenium.remote.RemoteWebElement.java

Source

// 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<File> 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<WebElement> 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<WebElement> 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<WebElement> allElements;
        try {
            allElements = (List<WebElement>) responseValue;
        } catch (ClassCastException ex) {
            throw new WebDriverException("Returned value cannot be converted to List<WebElement>: " + 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<WebElement> findElementsById(String using) {
        return findElements("id", using);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    protected Response execute(String command, Map<String, ?> 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<String, Object> rawPoint = (Map<String, Object>) 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<String, Object> rawSize = (Map<String, Object>) 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<String, Object> rawRect = (Map<String, Object>) 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<String, Number> mapped = (Map<String, Number>) 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> X getScreenshotAs(OutputType<X> 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<String, Object> toJson() {
        return ImmutableMap.of(Dialect.OSS.getEncodedElementKey(), getId(), Dialect.W3C.getEncodedElementKey(),
                getId());
    }
}