Blame view

src/main/java/pl/labno/bernard/htmlunified/WebClientUtils.java 7.57 KB
bernard authored
1 2 3
package pl.labno.bernard.htmlunified;

import com.gargoylesoftware.htmlunit.WebClient;
bernard authored
4
import com.gargoylesoftware.htmlunit.html.DomNode;
bernard authored
5 6
import com.gargoylesoftware.htmlunit.html.DomNodeList;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
tomek authored
7
import com.gargoylesoftware.htmlunit.html.HtmlInput;
bernard authored
8
import com.gargoylesoftware.htmlunit.html.HtmlPage;
tomek authored
9 10
import com.gargoylesoftware.htmlunit.html.HtmlSpan;
import com.gargoylesoftware.htmlunit.html.HtmlTable;
bernard authored
11
import com.gargoylesoftware.htmlunit.html.HtmlTableCell;
tomek authored
12
import com.gargoylesoftware.htmlunit.html.HtmlTableRow;
bernard authored
13
tomek authored
14
import java.io.IOException;
bernard authored
15
import java.util.ArrayList;
bernard authored
16
import java.util.HashMap;
bernard authored
17
import java.util.List;
bernard authored
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
import java.util.Map;

public class WebClientUtils {

    private static long defaultCheckInterval = 500;
    private static long defaultTimeout = 10000;

    public static long getDefaultCheckInterval() {
        return defaultCheckInterval;
    }

    public static void setDefaultCheckInterval(long defaultCheckInterval) {
        WebClientUtils.defaultCheckInterval = defaultCheckInterval;
    }

    public static long getDefaultTimeout() {
        return defaultTimeout;
    }

    public static void setDefaultTimeout(long defaultTimeout) {
        WebClientUtils.defaultTimeout = defaultTimeout;
    }
bernard authored
41 42
    public static int waitForJSJob(String message, WebClient webClient) {
        return waitForJSJob(message, webClient, webClient.waitForBackgroundJavaScript(10) - 1);
bernard authored
43 44
    }
bernard authored
45 46
    public static int waitForJSJob(String message, WebClient webClient, int initialJobCount) {
        return waitForJSJob(message, webClient, initialJobCount, defaultTimeout);
bernard authored
47 48
    }
bernard authored
49 50
    public static int waitForJSJob(WebClient webClient, int initialJobCount, int timeout) {
        return waitForJSJob(null, webClient, initialJobCount, timeout);
bernard authored
51 52
    }
bernard authored
53 54 55 56 57 58 59 60 61
    public static int waitForJSJob(String message, WebClient webClient, int initialJobCount, long timeout) {
        return waitForJSJob(message, webClient, initialJobCount, timeout, defaultCheckInterval);
    }

    public static int waitForJSJob(String message, WebClient webClient, int initialJobCount, int timeout) {
        return waitForJSJob(message, webClient, initialJobCount, timeout, defaultCheckInterval);
    }

    public static int waitForJSJob(String message, WebClient webClient, int initialJobCount, long timeout, long checkInterval) {
bernard authored
62 63 64 65 66
        int jobs;
        long startTime = System.currentTimeMillis();
        do {
            jobs = webClient.waitForBackgroundJavaScript(checkInterval);
            if (startTime + timeout < System.currentTimeMillis()) {
bernard authored
67
                throw new RuntimeException("Number of JavaScript jobs doesn't drop to initial level for " + timeout + " seconds. It's memory leak in your JavaScript rather then request taking so long!");
bernard authored
68 69
            }
        } while (jobs > initialJobCount);
bernard authored
70
        System.out.println("Waiting" + (message == null ? "" : " for " + message) + " took: " + (System.currentTimeMillis() - startTime) + "ms");
bernard authored
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
        return jobs;
    }

    /**
     * Returns list of suggestions from rich:suggestionBox
     *
     * @param suggestion suggestionBox element
     * @param column     column of suggestionBox to extract text from
     * @return list of suggestions
     */
    public static Map<String, HtmlTableCell> getSuggestions(HtmlElement suggestion, int column) {
        final Map<String, HtmlTableCell> suggestions = new HashMap<String, HtmlTableCell>();
        final HtmlElement suggestElement = suggestion.getElementById(suggestion.getId() + ":suggest");
        @SuppressWarnings("unchecked")
        final DomNodeList<HtmlElement> suggestionRows = suggestElement.getElementsByTagName("tr");
        for (HtmlElement row : suggestionRows) {
tomek authored
87 88 89 90 91 92
            if (!row.getId().endsWith("NothingLabel")) {
                @SuppressWarnings("unchecked")
                final DomNodeList<HtmlElement> cells = row.getElementsByTagName("td");
                final HtmlTableCell cell = (HtmlTableCell) cells.get(column + 1);
                suggestions.put(cell.asText(), cell);
            }
bernard authored
93 94 95
        }
        return suggestions;
    }
bernard authored
96 97 98 99 100 101 102 103 104 105 106 107 108 109

    public static void forceWait(int timeout) {
        final long startTime = System.currentTimeMillis();
        do {
            try {
                final long millis = startTime + timeout - System.currentTimeMillis();
                if (millis > 0) {
                    Thread.sleep(millis);
                }
            } catch (InterruptedException ignore) {
            } catch (IllegalArgumentException ignore) {
            }
        } while (startTime + timeout > System.currentTimeMillis());
    }
bernard authored
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

    public static void executeAjaxReRenderedScripts(HtmlPage page) {
        final DomNodeList<HtmlElement> scripts = page.getElementsByTagName("script");
        /**
         * We cannot iterate over html DomNodeList cause it depends on sibling relationship which we will modify.
         */
        final List<HtmlElement> scriptsList = new ArrayList<HtmlElement>();
        for (HtmlElement element : scripts) {
            scriptsList.add(element);
        }
        for (HtmlElement element : scriptsList) {
            if (element.getChildNodes().size() > 1) {
                element.removeChild(element.getFirstChild());
                final DomNode sibling = element.getNextSibling();
                final DomNode parentNode = element.getParentNode();
                /**
                 * Script will be executed upon inserting into DOM tree, so we removed and add it again.
                 */
                if (sibling != null) {
                    parentNode.removeChild(element);
                    sibling.insertBefore(element);
                } else {
                    parentNode.removeChild(element);
                    parentNode.appendChild(element);
                }
            }
        }
    }
tomek authored
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153

    public static void setColorPickerValue(WebClient webClient, HtmlElement colorPicker, String hex) throws IOException {
        HtmlPage page = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();
        colorPicker.click();
        ((HtmlInput) page.getElementById(colorPicker.getId() + "-colorPicker-hex")).setValueAttribute(hex);
        page.getElementById(colorPicker.getId() + "-colorPicker-popup").getHtmlElementsByTagName("button").get(0).click();
    }

    public static void setColorPickerValue(WebClient webClient, HtmlElement colorPicker, int red, int green, int blue) throws IOException {
        HtmlPage page = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();
        colorPicker.click();
        ((HtmlInput) page.getElementById(colorPicker.getId() + "-colorPicker-rgb-r")).setValueAttribute(Integer.toString(red));
        ((HtmlInput) page.getElementById(colorPicker.getId() + "-colorPicker-rgb-g")).setValueAttribute(Integer.toString(green));
        ((HtmlInput) page.getElementById(colorPicker.getId() + "-colorPicker-rgb-b")).setValueAttribute(Integer.toString(blue));
        page.getElementById(colorPicker.getId() + "-colorPicker-popup").getHtmlElementsByTagName("button").get(0).click();
    }
tomek authored
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

    @SuppressWarnings("unchecked")
    public static List<HtmlTableRow> getTableRows(HtmlTable table) {
        return (List<HtmlTableRow>) table.getByXPath(".//*[contains(@class,'rich-table-row')]");
    }

    @SuppressWarnings("unchecked")
    public static List<String> getScheduleEventTitles(HtmlElement schedule) {
        final List<HtmlSpan> titleElements = (List<HtmlSpan>) schedule.getByXPath(".//*[@class='fc-event-title']");
        List<String> titles = new ArrayList<String>(titleElements.size());
        for (HtmlSpan o : titleElements) {
            titles.add(o.asText());
        }
        return titles;
    }
bernard authored
169
}