001/*
002 * (C) Copyright 2014 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 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.functionaltests;
018
019import java.util.concurrent.TimeUnit;
020
021import org.openqa.selenium.JavascriptExecutor;
022import org.openqa.selenium.NoSuchElementException;
023import org.openqa.selenium.WebDriver;
024import org.openqa.selenium.support.ui.FluentWait;
025import org.openqa.selenium.support.ui.Wait;
026
027import com.google.common.base.Function;
028
029/**
030 * @since 6.0
031 */
032public class AjaxRequestManager {
033
034    protected JavascriptExecutor js;
035
036    protected boolean active;
037
038    protected int count;
039
040    public AjaxRequestManager(WebDriver driver) {
041        super();
042        js = (JavascriptExecutor) driver;
043        reset();
044    }
045
046    protected void reset() {
047        active = false;
048        count = 0;
049    }
050
051    /**
052     * @since 7.2
053     */
054    public void begin() {
055        StringBuilder sb = new StringBuilder();
056        sb.append("if (window.ajaxListenerSet === undefined) {");
057        sb.append("window.ajaxListenerSet = true;");
058        sb.append("window.NuxeoTestFaces = function() {");
059        sb.append("  var e = {};");
060        sb.append("  e.jsf2AjaxRequestStarted = false;");
061        sb.append("  e.jsf2AjaxRequestFinished = false;");
062        sb.append("  e.jsf2AjaxRequestActiveCount = 0;");
063        sb.append("  e.increment = function() {");
064        sb.append("    e.jsf2AjaxRequestStarted = true;");
065        sb.append("    e.jsf2AjaxRequestFinished = false;");
066        sb.append("    e.jsf2AjaxRequestActiveCount++;");
067        sb.append("  };");
068        sb.append("  e.decrement = function() {");
069        sb.append("    e.jsf2AjaxRequestActiveCount--;");
070        sb.append("    if (e.jsf2AjaxRequestActiveCount == 0) {");
071        sb.append("      e.jsf2AjaxRequestFinished = true;");
072        sb.append("    }");
073        sb.append("  };");
074        sb.append("  e.finished = function() {");
075        sb.append("    return e.jsf2AjaxRequestStarted && e.jsf2AjaxRequestFinished;");
076        sb.append("  };");
077        sb.append(" return e");
078        sb.append("}();");
079        sb.append("if (typeof jsf !== 'undefined') {");
080        sb.append("  jsf.ajax.addOnEvent(function(e) {"
081                + "if (e.status == 'begin') {window.NuxeoTestFaces.increment();}"
082                + "if (e.status == 'success') {window.NuxeoTestFaces.decrement();}" + "})");
083        sb.append("}");
084        sb.append("}");
085        js.executeScript(sb.toString());
086    }
087
088    public void watchAjaxRequests() {
089        begin();
090    }
091
092    /**
093     * @since 7.2
094     */
095    public void end() {
096        waitUntil((new Function<WebDriver, Boolean>() {
097            @Override
098            public Boolean apply(WebDriver driver) {
099                Boolean res = (Boolean) js.executeScript("return window.NuxeoTestFaces.finished();");
100                return res;
101            }
102        }));
103    }
104
105    public void waitForAjaxRequests() {
106        end();
107    }
108
109    /**
110     * @since 7.1
111     */
112    public void waitForJQueryRequests() {
113        waitUntil(new Function<WebDriver, Boolean>() {
114            @Override
115            public Boolean apply(WebDriver driver) {
116                Boolean res = (Boolean) ((JavascriptExecutor) driver).executeScript("return jQuery.active == 0;");
117                return res;
118            }
119        });
120    }
121
122    private void waitUntil(Function<WebDriver, Boolean> function) {
123        Wait<WebDriver> wait = new FluentWait<WebDriver>(AbstractTest.driver).withTimeout(
124                AbstractTest.LOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS).pollingEvery(
125                AbstractTest.POLLING_FREQUENCY_MILLISECONDS, TimeUnit.MILLISECONDS).ignoring(
126                NoSuchElementException.class);
127        wait.until(function);
128    }
129}