io.github.seleniumquery.utils.WebElementUtils.java Source code

Java tutorial

Introduction

Here is the source code for io.github.seleniumquery.utils.WebElementUtils.java

Source

/*
 * Copyright (c) 2015 seleniumQuery authors
 *
 * Licensed 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 io.github.seleniumquery.utils;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import io.github.seleniumquery.functions.jquery.attributes.PropFunction;

/**
 * Several functions for simplified dealing with {@link WebElement}s.
 *
 * @author acdcjunior
 * @since 0.9.0
 */
public class WebElementUtils {

    private WebElementUtils() {
    }

    public static boolean elementHasAttribute(WebElement element, String attributeName, String attributeValue) {
        return attributeValue.equalsIgnoreCase(element.getAttribute(attributeName));
    }

    public static boolean isTextareaTag(WebElement element) {
        return "textarea".equals(element.getTagName());
    }

    public static boolean isSelectTag(WebElement element) {
        return "select".equals(element.getTagName());
    }

    public static boolean isOptionTag(WebElement element) {
        return "option".equals(element.getTagName());
    }

    public static boolean isInputTag(WebElement element) {
        return "input".equals(element.getTagName());
    }

    public static boolean isInputFileTag(WebElement element) {
        return isInputTagWithType(element, "file");
    }

    private static boolean isInputTagWithType(WebElement element, String file) {
        return isInputTag(element) && elementHasAttribute(element, "type", file);
    }

    public static boolean isInputRadioTag(WebElement element) {
        return isInputTagWithType(element, "radio");
    }

    public static boolean isInputCheckboxTag(WebElement element) {
        return isInputTagWithType(element, "checkbox");
    }

    public static boolean isInputHiddenTag(WebElement element) {
        return isInputTagWithType(element, "hidden");
    }

    public static boolean isInputButtonTag(WebElement element) {
        return isInputTagWithType(element, "button");
    }

    public static boolean isInputSubmitTag(WebElement element) {
        return isInputTagWithType(element, "submit");
    }

    /*
     * To be contenteditable, an element must:
     *  - have @contenteditable=""
     *  - have @contenteditable="true"
     * OR
     *  - have an ancestor that is contenteditable closer than one that is not.
     *
     * If an element has @contenteditable="false" it is NOT contenteditable (this is the only way to mark it as not C.E.)
     *
     * If the @contenteditable is any other value (that is, not "", "true" or "false"), then it is "inherit".
     *
     * E.g. If an alement has a grandfather that is editable, but a father that is not (ce attr=false), then it is not. So it is
     * not sufficient to search for parents that are editable.
     *
     *
     * OLD ALGORITHM:
     * <pre><code>
     * public static boolean isContentEditable(WebElement element) {
     *     if (element == null) {
     *         return false;
     *     }
     *     String contenteditable = element.getAttribute("contenteditable");
     *     if ("false".equalsIgnoreCase(contenteditable)) {
     *         return false;
     *     }
     *     if ("".equals(contenteditable) || "true".equalsIgnoreCase(contenteditable)) {
     *         return true;
     *     }
     *     // no contenteditable attribute; or
     *     // contenteditable == "inherit"; or
     *     // contenteditable == "anything";
     *     // then we consider as "inherit" - aka its value is the value of its father's contenteditable
     *     return isContentEditable(SelectorUtils.parent(element));
     * }
     * <pre><code>
     */
    public static boolean isContentEditable(WebDriver driver, WebElement element) {
        if (!DriverVersionUtils.isHtmlUnitWithDisabledJavaScript(driver)) {
            return PropFunction.prop(driver, element, "isContentEditable");
        }
        // only use XPath on HtmlUnit with JS OFF
        return !element.findElements(By.xpath("self::node()["
                + "ancestor-or-self::*[@contenteditable=\"\" or @contenteditable=\"true\" or @contenteditable=\"false\"][1]/@contenteditable = \"\""
                + " or "
                + "ancestor-or-self::*[@contenteditable=\"\" or @contenteditable=\"true\" or @contenteditable=\"false\"][1]/@contenteditable = \"true\""
                + "]")).isEmpty();
    }

}