package com.xceptance.xlt.common.actions;
import java.io.IOException;
import java.util.List;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.xceptance.common.util.ParameterCheckUtils;
import com.xceptance.xlt.api.actions.AbstractHtmlPageAction;
import com.xceptance.xlt.api.actions.AbstractWebAction;
import com.xceptance.xlt.api.engine.NetworkData;
import com.xceptance.xlt.api.engine.Session;
import com.xceptance.xlt.api.util.XltProperties;
import com.xceptance.xlt.common.XltConstants;
import com.xceptance.xlt.engine.SessionImpl;
import com.xceptance.xlt.engine.XltWebClient;
/**
* This class is simply a variant of the {@link AbstractHtmlPageAction}. They distinguish in the method
* {@link #loadPage(WebRequest)}. In this class it is possible to pass a {@link WebRequest}, which is cozy.
*/
public abstract class ModifiedAbstractHtmlPageAction extends AbstractWebAction
{
private static final String PROP_JS_BACKGROUND_ACTIVITY_WAITINGTIME = XltConstants.XLT_PACKAGE_PATH +
".js.backgroundActivity.waitingTime";
private static final long DEFAULT_JS_BACKGROUND_ACTIVITY_WAITINGTIME = XltProperties.getInstance()
.getProperty(PROP_JS_BACKGROUND_ACTIVITY_WAITINGTIME,
0);
private HtmlPage htmlPage;
protected ModifiedAbstractHtmlPageAction(final ModifiedAbstractHtmlPageAction previousAction, final String timerName)
{
super(previousAction, timerName);
}
protected ModifiedAbstractHtmlPageAction(final String timerName)
{
this(null, timerName);
}
protected void loadPage(final WebRequest webRequest) throws FailingHttpStatusCodeException, IOException
{
loadPage(webRequest, DEFAULT_JS_BACKGROUND_ACTIVITY_WAITINGTIME);
}
protected void loadPage(final WebRequest webRequest, final long waitingTime) throws FailingHttpStatusCodeException, IOException
{
final Page result = getWebClient().getPage(webRequest);
this.htmlPage = waitForPageIsComplete(result, waitingTime);
}
private HtmlPage waitForPageIsComplete(final Page page, final long waitingTime)
{
// wait for any JavaScript background thread to finish
if (page instanceof SgmlPage)
{
final XltWebClient webClient = (XltWebClient) ((SgmlPage) page).getWebClient();
webClient.waitForBackgroundThreads(page.getEnclosingWindow().getTopWindow().getEnclosedPage(), waitingTime);
}
// something might have changed, including a reload via location
final HtmlPage newHtmlPage = (HtmlPage) page.getEnclosingWindow().getTopWindow().getEnclosedPage();
// check for any new static content to load
((XltWebClient) newHtmlPage.getWebClient()).loadNewStaticContent(newHtmlPage);
// Feature #471: API: Make the network data available for validation
collectAndSetNetworkData();
return newHtmlPage;
}
private List<NetworkData> netStats = null;
private void collectAndSetNetworkData()
{
netStats = Session.getCurrent().getNetworkDataManager().getData();
}
public HtmlPage getHtmlPage()
{
return this.htmlPage;
}
protected List<NetworkData> getNetworkDataSet()
{
return netStats;
}
@Override
public ModifiedAbstractHtmlPageAction getPreviousAction()
{
return (ModifiedAbstractHtmlPageAction) super.getPreviousAction();
}
@Override
public void run() throws Throwable
{
try
{
super.run();
}
finally
{
/*
* Dump the page not before the very end of this action. This way, all requests that are executed after one
* of the loadPageByXXX() methods are correctly associated with this action.
*/
dumpPage(getHtmlPage());
Session.getCurrent().getNetworkDataManager().clear();
}
}
public void setHtmlPage(final HtmlPage htmlPage)
{
setHtmlPage(htmlPage, DEFAULT_JS_BACKGROUND_ACTIVITY_WAITINGTIME);
}
public void setHtmlPage(final HtmlPage htmlPage, final long waitingTime)
{
ParameterCheckUtils.isNotNull(htmlPage, "htmlPage");
this.htmlPage = waitForPageIsComplete(htmlPage, waitingTime);
}
private void dumpPage(final HtmlPage htmlPage)
{
if (htmlPage != null)
{
final String timerName = ((XltWebClient) getWebClient()).getTimerName();
((SessionImpl) Session.getCurrent()).getRequestHistory().add(timerName, htmlPage);
}
}
}