001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 */
014package org.nuxeo.functionaltests;
015
016import com.google.common.base.Function;
017import org.openqa.selenium.JavascriptExecutor;
018import org.openqa.selenium.NoSuchElementException;
019import org.openqa.selenium.WebDriver;
020import org.openqa.selenium.support.ui.FluentWait;
021import org.openqa.selenium.support.ui.Wait;
022
023import java.util.concurrent.TimeUnit;
024
025/**
026 * @since 7.10
027 */
028public class EventListener {
029
030    private static int COUNT = 0;
031
032    private final String id = "evt_listener_" + COUNT++;
033
034    private final String event;
035
036    private final String selector;
037
038    private final JavascriptExecutor js;
039
040    public EventListener(WebDriver driver, String event, String selector) {
041        super();
042        this.event = event;
043        this.selector = selector;
044        js = (JavascriptExecutor) driver;
045        listen();
046    }
047
048    public void listen() {
049        StringBuilder sb = new StringBuilder();
050        sb.append("window."+ id + " = 0;");
051        sb.append("var els = document.querySelectorAll('" + selector +"');");
052        sb.append("for (var i=0; i<els.length; i++) {");
053        sb.append("  els[i].addEventListener('" + event + "', function(e) { window."+ id + "++; });");
054        sb.append("}");
055        js.executeScript(sb.toString());
056    }
057
058    public void waitCalled() {
059        waitCalled(1);
060    }
061
062    public void waitCalled(int times) {
063        waitUntil(driver -> (Boolean) js.executeScript("return window." + id + " == " + times + ";"));
064    }
065
066    public void reset() {
067        js.executeScript("window." + id + " = 0;");
068    }
069
070    private void waitUntil(Function<WebDriver, Boolean> function) {
071        Wait<WebDriver> wait = new FluentWait<WebDriver>(AbstractTest.driver).withTimeout(
072            AbstractTest.LOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS).pollingEvery(
073            AbstractTest.POLLING_FREQUENCY_MILLISECONDS, TimeUnit.MILLISECONDS).ignoring(
074            NoSuchElementException.class);
075        wait.until(function);
076    }
077
078}