001/**
002 * Copyright 2005-2017 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.testtools.selenium;
017
018import org.openqa.selenium.JavascriptExecutor;
019import org.openqa.selenium.WebDriver;
020import org.openqa.selenium.WebElement;
021
022import java.io.BufferedReader;
023import java.io.IOException;
024import java.io.InputStream;
025import java.io.InputStreamReader;
026import java.util.LinkedList;
027import java.util.List;
028
029/**
030 * Utility for highlighting a WebDriver WebElement in green (#66FF33) for 400ms.  Executes JavaScript to change the
031 * WebElement style and then revert back to the original style.  Set the JVM argument -Dremote.driver.highlight=true to
032 * enable.
033 *
034 * @author Kuali Rice Team (rice.collab@kuali.org)
035 */
036public class WebDriverHighlightHelper {
037
038    protected boolean jsHighlightEnabled = false;
039
040    /**
041     * green (#66FF33)
042     */
043    public static final String JS_HIGHLIGHT_BACKGROUND = "#66FF33";
044
045    /**
046     * green (#66FF33)
047     */
048    public static final String JS_HIGHLIGHT_BOARDER = "#66FF33";
049
050    /**
051     * 400 milliseconds.
052     */
053    public static final int JS_HIGHLIGHT_MS = 400;
054
055    /**
056     * <p>
057     * {@see JS_HIGHLIGHT_MS} as default.
058     * </p><p>
059     * -Dremote.driver.highlight.ms=
060     * </p>
061     */
062    public static final String JS_HIGHLIGHT_MS_PROPERTY = "remote.driver.highlight.ms";
063
064    /**
065     * <p>
066     * Highlighting of elements as selenium runs.
067     * </p><p>
068     * -Dremote.driver.highlight=true
069     * </p>
070     */
071    public static final String JS_HIGHLIGHT_PROPERTY = "remote.driver.highlight";
072
073    /**
074     * TODO: playback for javascript highlighting.
075     *
076     * -Dremote.driver.highlight.input=
077     */
078    public static final String JS_HIGHLIGHT_INPUT_PROPERTY = "remote.driver.highlight.input";
079
080    /**
081     * Create a WebDriverHighlightHelp which is enabled if JS_HIGHLIGHT_PROPERTY is set to true.
082     */
083    public WebDriverHighlightHelper() {
084        if ("true".equals(System.getProperty(JS_HIGHLIGHT_PROPERTY, "false"))) {
085            jsHighlightEnabled = true;
086            if (System.getProperty(JS_HIGHLIGHT_INPUT_PROPERTY) != null) {
087                InputStream in = WebDriverUtils.class.getResourceAsStream(System.getProperty(JS_HIGHLIGHT_INPUT_PROPERTY));
088                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
089                String line = null;
090                List<String> lines = new LinkedList<String>();
091                try {
092                    while ((line = reader.readLine()) != null) {
093                        lines.add(line);
094                    }
095                } catch (IOException e) {
096                    System.out.println("Error reading javascript highlight playback file " + System.getProperty(JS_HIGHLIGHT_INPUT_PROPERTY));
097                    e.printStackTrace();
098                }
099            }
100        }
101    }
102
103    /**
104     * <p>
105     * Highlight given WebElement.
106     * </p>
107     *
108     * @param webDriver to execute highlight on
109     * @param webElement to highlight
110     */
111    public void highlightElement(WebDriver webDriver, WebElement webElement) {
112        if (jsHighlightEnabled && webElement != null) {
113            try {
114                //                System.out.println("highlighting " + webElement.toString() + " on url " + webDriver.getCurrentUrl());
115                JavascriptExecutor js = (JavascriptExecutor) webDriver;
116                String jsHighlight = "element = arguments[0];\n"
117                        + "originalStyle = element.getAttribute('style');\n"
118                        + "element.setAttribute('style', originalStyle + \"; background: "
119                        + JS_HIGHLIGHT_BACKGROUND + "; border: 2px solid " + JS_HIGHLIGHT_BOARDER + ";\");\n"
120                        + "setTimeout(function(){\n"
121                        + "    element.setAttribute('style', originalStyle);\n"
122                        + "}, " + System.getProperty(JS_HIGHLIGHT_MS_PROPERTY, JS_HIGHLIGHT_MS + "") + ");";
123                js.executeScript(jsHighlight, webElement);
124            } catch (Throwable t) {
125                System.out.println("Throwable during javascript highlight element");
126                t.printStackTrace();
127            }
128        }
129    }
130}