Author: ozizka(a)redhat.com
Date: 2009-03-19 23:26:13 -0400 (Thu, 19 Mar 2009)
New Revision: 245
Modified:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AppConstants.java
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/EarTest.java
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/WarTest.java
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/ActiveConditionChecker.java
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/EmbJoprTestToolkit.java
Log:
WAR tests created, EAR tests updated, EJTT updates.
EmbjoprTestCase: getNavTreeLink() - changed ID of the Delete button -
"resourceSummaryForm:" prepended
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AppConstants.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AppConstants.java 2009-03-20
03:11:17 UTC (rev 244)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/AppConstants.java 2009-03-20
03:26:13 UTC (rev 245)
@@ -30,6 +30,7 @@
+
/**
* Information about deployable types -
* navigation tree labels, archive extensions,
@@ -38,18 +39,22 @@
public enum DeployableTypes {
// Mandatory: first, fourth
- EAR(AppConstants.NAV_EAR, ".ear", null, "application/ear"),
- WAR(AppConstants.NAV_WAR, ".war", null, "application/war"),
- EJB(AppConstants.NAV_EJB, ".jar", null,
" application/java-archive"),
- SAR(AppConstants.NAV_SAR, ".sar", "-service.xml",
"application/sar"),
- RAR(AppConstants.NAV_RAR, ".rar", null, "application/rar"),
- MC_BEAN(AppConstants.NAV_MC, "", null,
"application/java-archive");
+ // Nav tree link label, testdata/$dir, extension, suffix, mime type.
+ EAR(AppConstants.NAV_EAR, "ear", ".ear", null,
"application/ear"),
+ WAR(AppConstants.NAV_WAR, "war", ".war", null,
"application/war"),
+ EJB(AppConstants.NAV_EJB, "ejb", ".jar", null,
" application/java-archive"),
+ SAR(AppConstants.NAV_SAR, "sar", ".sar",
"-service.xml", "application/sar"),
+ RAR(AppConstants.NAV_RAR, "rar", ".rar", null,
"application/rar"),
+ MC_BEAN(AppConstants.NAV_MC, "mc", "", null,
"application/java-archive");
// -- Fields --
protected final String navTreeLabel;
public String getNavTreeLabel() { return navTreeLabel; }
+ protected final String dataDir;
+ public String getDataDir() { return dataDir; }
+
protected final String extension;
public String getExtension() { return extension; }
@@ -61,13 +66,17 @@
+
// -- Constructors --
private DeployableTypes(
- String navTreeLabel, String extension,
+ String navTreeLabel,
+ String dataDir,
+ String extension,
String suffix, String mimeType)
{
this.navTreeLabel = navTreeLabel;
+ this.dataDir = dataDir;
this.extension = extension;
this.suffix = suffix;
this.mimeType = mimeType;
@@ -75,8 +84,8 @@
}// enum DeployableTypes
+
-
/** Several ways how to deploy / undeploy. */
public enum DeploymentMeans {
VIA_EMBJOPR,
@@ -98,14 +107,19 @@
public static final String NAV_WAR = "Web Application (WAR)s";
public static final String EAR_MALFORMED_APP_FILENAME =
"malformed-application-xml.ear";
+ public static final String WAR_FILENAME_MALFORMED_APP =
"malformed-web-xml.war";
// Test Archives
public static final String BASIC_JAR = "deployment-ejb.jar";
public static final String BASIC_EAR = "eardeployment.ear";
public static final String EAR_UNPACKED = "unpacked-ear1.ear";
public static final String EAR_UNPACKED_ZIP = "unpacked-ear1.ear.zip";
+
public static final String BASIC_WAR = "hellothere.war";
+ public static final String WAR_UNPACKED = "unpacked-web1.war";
+ public static final String WAR_UNPACKED_ZIP = "unpacked-web1.war.zip";
+
// Defaults
public static final String[] WAR_DEFAULTS = new String[]{
"ROOT.war", "invoker.war",
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-03-20
03:11:17 UTC (rev 244)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/EmbjoprTestCase.java 2009-03-20
03:26:13 UTC (rev 245)
@@ -155,7 +155,8 @@
String id = link.getIdAttribute();
String[] idElements = id.split(":");
String row = idElements[idElements.length - 2];
- return (HtmlButtonInput)client.getElement("dataTable:" + row +
":removeButton");
+ // resourceSummaryForm:dataTable:2:removeButton
+ return
(HtmlButtonInput)client.getElement("resourceSummaryForm:dataTable:" + row +
":removeButton");
}
/**
@@ -173,9 +174,7 @@
if (linkText.contains(linkLabel)) return link;
}
- throw new IllegalStateException("Link for '"
- + linkLabel
- + "' not found.");
+ throw new IllegalStateException("Link for '"+ linkLabel
+"' not found.");
}
/**
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/EarTest.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/EarTest.java 2009-03-20
03:11:17 UTC (rev 244)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/EarTest.java 2009-03-20
03:26:13 UTC (rev 245)
@@ -434,7 +434,7 @@
/**
- * Changes EAR configuration, and checks whether the changes were saved.
+ * Changes EAR configuration, and verifies that the changes were NOT saved.
*
* FAILS because some of the values are read-only. EMBJOPR-96
*/
@@ -457,8 +457,8 @@
// Load properties (we will use their names).
Properties propsToSet = new Properties();
- String filePath =
ejtt.getTestDataDir()+"/ear/"+"ear-conf-basic.properties";
- propsToSet.load(new FileInputStream( filePath ));
+ String propsFilePath =
ejtt.getTestDataDir()+"/ear/"+"ear-conf-basic.properties";
+ propsToSet.load(new FileInputStream( propsFilePath ));
// Get the current properties.
Properties propsOriginal = getFormPropertiesValues( propsToSet );
@@ -485,9 +485,7 @@
/**
- * Changes EAR configuration, and checks whether the changes were saved.
- *
- * FAILS because some of the values are read-only. EMBJOPR-96
+ * Redeploys EAR.
*/
public void testEarRedeployment() throws IOException, EmbJoprTestException {
@@ -526,9 +524,9 @@
/**
* Deploys exploded EAR and checks whether it is reported as exploded.
*
- * FAILS: EMBJOPR-95
+ * DISABLED - Badly written test, to be fixed. TODO: Hot-deploy
*/
- public void testUnzippedEarReportedAsExploded() throws IOException, EmbJoprTestException
{
+ public void DISABLEDtestUnzippedEarReportedAsExploded() throws IOException,
EmbJoprTestException {
// Deploy the EAR.
String earFilePath = ejtt.getTestDataDir() + "/ear/"+BASIC_EAR;
@@ -665,7 +663,7 @@
}
finally {
// Delete the EAR dir.
- deleteFromDeployDir(EAR_UNPACKED_ZIP);
+ deleteFromDeployDir(EAR_UNPACKED);
}
}
@@ -845,7 +843,7 @@
- // TODO: Move to utils
+ // TODO: Moved to EJTT, remove from here.
private void deleteFromDeployDir( String deployableName ) throws IOException{
String deployDir = ejtt.getDeployDir();
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/WarTest.java
===================================================================
--- trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/WarTest.java 2009-03-20
03:11:17 UTC (rev 244)
+++ trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/as5/WarTest.java 2009-03-20
03:26:13 UTC (rev 245)
@@ -22,36 +22,43 @@
package org.jboss.jopr.jsfunit.as5;
+import javax.faces.context.FacesContext;
+import javax.servlet.http.HttpServletRequest;
+import com.gargoylesoftware.htmlunit.WebClient;
+import org.jboss.jopr.jsfunit.util.EmbJoprTestToolkit.*;
+
import org.jboss.jopr.jsfunit.*;
import com.gargoylesoftware.htmlunit.html.*;
-import java.io.IOException;
+import java.io.*;
+import java.util.Properties;
+import javax.faces.application.FacesMessage;
import junit.framework.Test;
import junit.framework.TestSuite;
-import javax.faces.context.FacesContext;
-import javax.servlet.http.HttpServletRequest;
-import com.gargoylesoftware.htmlunit.WebClient;
-import java.io.File;
-import java.io.FileNotFoundException;
-import org.jboss.jopr.jsfunit.exceptions.ActionNotAvailableException;
-import org.jboss.jopr.jsfunit.exceptions.HtmlElementNotFoundException;
+import org.apache.commons.lang.math.RandomUtils;
+import org.jboss.jopr.jsfunit.exceptions.*;
+import org.jboss.jopr.jsfunit.util.ActiveConditionChecker;
+import org.jboss.jopr.jsfunit.util.DescribedCondition;
+import org.jboss.jopr.jsfunit.util.EmbJoprTestToolkit.*;
+import org.w3c.dom.Node;
-
-
/**
* This class contains tests for testing the EmbJopr Application
* Management Functions for Web Components with JBoss AS 5.
- *
- * @author Shelly McGowan
*
+ * Most tests currently fail because of
+ * JBAS-6640: Undeploying and deploying the same WAR in short time fails.
*/
public class WarTest extends ApplicationTestBaseAS5 {
+ public static final int DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL = 6000;
+ public static final int DEPLOY_UP_STATE_WAIT_CHECK_RETRIES = 50;
+
+
+
/**
- * @return the suite of tests being tested
- */
-
- public static Test suite()
- {
+ * @return the suite of tests being tested
+ */
+ public static Test suite() {
return new TestSuite(WarTest.class);
}
@@ -90,6 +97,10 @@
HtmlPage page = (HtmlPage)webClient.getPage("http://localhost:" + port +
"/hellothere/hello.jsp");
assertTrue(page.asText().contains("HELLO WORLD"));
+ }
+ finally {
+ //undeployWAR(BASIC_WAR);
+
// Undeploy the WAR
HtmlButtonInput deleteButton = getAppDeleteButton(BASIC_WAR);
deleteButton.click();
@@ -98,14 +109,598 @@
// reason, JBoss doesn't undeploy the MBeans
// JBAS-XXXX
//assertFalse(isWarDeployed(BASIC_WAR));
+
}
+ }
+
+
+
+
+
+
+ public void DISABLEDtestBadWarRedeploy() throws IOException,
HtmlElementNotFoundException, ActionNotAvailableException {
+
+ try {
+ String filePath = ejtt.getTestDataDir() +
"/war/"+AppConstants.WAR_FILENAME_MALFORMED_APP;
+ deployWAR(filePath);
+
+ checkClientAndServerMessages("Failed to create Resource", "Failed to
create Resource", true);
+ }
finally {
undeployWAR(BASIC_WAR);
}
}
+
+
+
+
+
+ public void testNavigationToWar() throws IOException, HtmlElementNotFoundException,
ActionOutOfSyncException, ActionNotAvailableException, EmbJoprTestException,
InterruptedException, ActionOutOfSyncException
+ {
+
+ // JBossAS Servers node
+ NavTreeNode nodeServers = ejtt.getNavTree().getNodeByLabel("JBossAS
Servers");
+ nodeServers.click();
+
+ {
+ String headerText = "JBossAS Server";
+
+ assertTrue("Page doesn't contain the header: "+headerText,
+ client.getPageAsText().contains(headerText));
+
+ assertTrue("EmbJopr should list at least one server (the one it is running
on)" +
+ " and that should be in the UP sate.",
+ client.getPageAsText().contains("UP"));
+ // Check whether the server is listed. If not, Exception is thrown.
+ ContentTableRow row =
+ ejtt.getTabMenu().getTabContentBox().getTableUnderHeader("JBoss Application
Server")
+ .getFirstRowContainingLink("JBoss App Server:default");
+ // Click the server link
+ //HtmlAnchor link row.getLinkByLabel("JBoss App Server:default");
+ Node firstLink =
row.getCellByColumnName("Name").getElementsByTagName("a").item(0);
+ if( null == firstLink || !(firstLink instanceof HtmlAnchor) )
+ throw new HtmlElementNotFoundException("Can't find the server link.");
+
+ ((HtmlAnchor)firstLink).click();
+ }
+
+ // JBoss App Server:${config} node
+ {
+ String pageText = client.getPageAsText();
+
+ String headerText = "JBoss App Server:default";
+ assertTrue("Page doesn't contain the header: "+headerText,
+ pageText.contains(headerText));
+
+ headerText = "General Properties";
+ assertTrue("Page doesn't contain the header: "+headerText,
+ pageText.contains(headerText));
+
+ // TODO: This page reports "Version:5.0 CR1" - EMBJOPR-77
+
+ ejtt.getNavTree().getNodeByLabel("Applications").click();
+
+ }
+
+
+ // Applications node
+ {
+ // Whooo-hooo! So much to click through!
+
+ ejtt.getTabMenu().clickTab("Summary");
+
+ // TODO: Pagination options: EMBJOPR-78
+ // resourceDataScroller.xhtml, TableManager.java, "pageSizes".
+
+
+ // There's at least one Application with State == UP.
+ //ContentTable table =
ejtt.getTabMenu().getTabContentBox().getTableUnderHeader("Different types of
Applications");
+ HtmlTable tableElement =
(HtmlTable)client.getElement("categorySummaryForm:dataTable");
+ ContentTable table = ejtt.getTabMenu().getTabContentBox().getTable(tableElement);
+ ContentTableRow row = table.getFirstRowContainingText("UP");
+
+ // Go further - try to click on any Application that is up.
+ HtmlAnchor link = row.getFirstLinkFromColumn("Name");
+ link.click();
+ }
+
+
+ {
+ // Go back to applications Sumary screen.
+ ejtt.getNavTree().getNodeByLabel("Applications").click();
+ }
+
+
+ // Concrete appliction node.
+ {
+
+ // Deploy the WAR.
+ String filePath = ejtt.getTestDataDir() + "/war/"+BASIC_WAR;
+ deployWarRepeatedly( filePath );
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+
+ // Get to the app through listing.
+ log.debug("Looking for row with: "+BASIC_WAR);
+
+ // Commented out: we would have to click trough pages.
+ //ContentTableRow row =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+ ContentTableRow row = ejtt.getTabMenu().getTabContentBox()
+ .findLinkRowInDataTableUsingPagination(BASIC_WAR);
+
+ assertTrue("Page doesn't list "+BASIC_WAR+" in Summary tab.",
row != null );
+
+ // Go to the summary through listed item.
+ row.getLinkByLabel(BASIC_WAR).click();
+ /**/
+
+
+ // Other way to get to app: through nav tree.
+ ejtt.getNavTree().getNodeArrow(NAV_WAR).click();
+ ejtt.navTree.waitUntilNodeLoadedByAjax(BASIC_WAR, 500, 15);
+ ejtt.navTree.getNodeByLabel(BASIC_WAR).click();
+ /**/
+
+
+ // Check that we have the summary tab for the selected WAR.
+ assertTrue( "WAR name "+BASIC_WAR+" not found in the content
box.",
+ ejtt.getTabMenu().getTabContentBox().getElement().getTextContent().contains(BASIC_WAR)
);
+
+ // Go to the summary through nav tree node.
+ NavTreeNode appNode = ejtt.getNavTree().getNodeByLabel(NAV_WAR);
+ if( !appNode.isExpanded() ){
+ log.info("Expanding.");
+ appNode.getArrowLink().click();
+ Thread.sleep(2000);
+ }
+ ejtt.getNavTree().getNodeByLabel(BASIC_WAR).click();
+ // Check that we have the summary tab for the selected WAR.
+ ejtt.getTabMenu().getTabContentBox().getElement().getTextContent().contains(BASIC_WAR);
+
+ undeployWAR(BASIC_WAR);
+
+ }
+
+
+ }// testNavigationToWar()
+
+
+
+
+
+
+
/**
+ * Tests the values shown in the Summary tab of WAR.
+ *
+ * FAILS because of: EMBJOPR-110
+ */
+ public void testWarSummaryTab() throws EmbJoprTestException, IOException, Exception {
+
+ final int DEPLOY_TIMEOUT_SEC = 120;
+
+ // Deploy the WAR
+ String appFilePath = System.getProperty(SYSPROP_TESTDATA_DIR) +
"/war/"+BASIC_WAR;
+ deployWarRepeatedly( appFilePath );
+
+ try {
+
+ // Wait until the WAR appears...
+ // Should be present when the page is reloaded.
+ // TODO: Replace with waitUntil~()
+ new ActiveConditionChecker(new DescribedCondition("WAR appears in Summary tab
list") {
+ public boolean isTrue() throws Exception {
+ // Refresh, then check.
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ContentTableRow appRow =
ejtt.getDefaultContentTable().findFirstRowContainingLink(BASIC_WAR);
+ return null != appRow;
+ }
+ }).dumpPageOnTimeout(this).throwOnTimeout().waitWithTimeout(2000, 5);
+ /**/
+
+
+ ContentTableRow appRow =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+
+ // Wait until the Status is "UP".
+ // TODO: Replace with ActiveConditionChecker.
+ int maxLoops = DEPLOY_TIMEOUT_SEC;
+ do {
+ String statusText = appRow.getCellTextByColumnName("Status");
+ log.debug("WAR Status: "+statusText);
+ if( "UP".equals(statusText) )
+ break;
+
+ // Refresh page after 1 second.
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ appRow = ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+
+ // We don't want an infinite loop by mistake.
+ if( maxLoops-- <= 0 ){
+ throw new EmbJoprTestException("WAR "+BASIC_WAR+" not UP after
"+DEPLOY_TIMEOUT_SEC+" seconds.");
+ }
+ } while( true );
+
+ // FAILS because of EMBJOPR-80.
+ appRow.getLinkByLabel(BASIC_WAR).click();
+
+
+ // Check the values in info table(s)
+
+ // General Properties
+ HtmlTable genpropTable =
ejtt.getTabMenu().getTabContentBox().getTableUnderHeader("General
Properties").getElement();
+ ContentInfoTable infoTable = ejtt.getContentInfoTable( genpropTable );
+ Properties props = infoTable.getProperties();
+ log.info("General Properties: "+props.toString());
+
+ assertEquals(BASIC_WAR, props.getProperty("Name").trim());
+ //assertEquals("?", props.getProperty("Version")); // TODO: Where
does RHQ get the version from?
+
+
+ // Resource Traits
+ infoTable = ejtt.getContentInfoTable(
+ ejtt.getTabMenu().getTabContentBox().getTableUnderHeader("Resource
Traits").getElement() );
+ props = infoTable.getProperties();
+ log.info("Resource Traits: "+props.toString());
+ log.debug("Path: "+props.getProperty("Path"));///
+
+
+ String path = ejtt.getDeployDir()+"/"+BASIC_WAR;
+ assertEquals(path, props.getProperty("Path").trim());
+ assertEquals("no", props.getProperty("Exploded?").trim());
+
+ // Metrics Summary
+ HtmlTable summaryTable =
ejtt.getTabMenu().getTabContentBox().getTableUnderHeader("Metrics
Summary").getElement();
+ infoTable = ejtt.getContentInfoTable(summaryTable);
+ // (nothing here yet)
+
+
+ }
+ finally {
+ // Undeploy the WAR
+ undeployWAR( BASIC_WAR );
+ }
+
+ }// testWarSummary()
+
+
+
+
+
+
+
+ /**
+ * Changes WAR configuration, and checks whether the changes were saved.
+ *
+ * FAILS because some of the values are read-only. EMBJOPR-96
+ */
+ public void testWarConfigurationTab() throws IOException, EmbJoprTestException,
HtmlElementNotFoundException, Exception {
+
+ // Deploy the WAR.
+ String filePath = ejtt.getTestDataDir() +"/war/"+ BASIC_WAR;
+ deployWarRepeatedly( filePath );
+
+ try {
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, BASIC_WAR,
DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+ // Navigate to the Configuration tab
+ ContentTableRow appRow =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+ appRow.getLinkByLabel(BASIC_WAR).click();
+ ejtt.tabMenu.clickConfigurationTab();
+
+ // Read properties.
+ Properties props = new Properties();
+ String propsFilePath =
ejtt.getTestDataDir()+"/war/"+"war-conf-basic.properties";
+ props.load(new FileInputStream( propsFilePath ));
+
+
+ // Set the configuration options and Save
+ fillOutForm(props);
+ //ejtt.getTabMenu().getTabContentBox().getButtonByLabel("Save");
+ ejtt.getClickableByID("resourceConfigurationForm:saveButton").click();
+
+
+ // Check whether the properties were saved.
+ ejtt.tabMenu.clickConfigurationTab();
+
+ // TODO: We don't see the success message! EMBJOPR-89
+ //checkClientAndServerMessages("successfully", "successfully",
false);
+
+ // FAILS because some of the values are read-only. EMBJOPR-96
+ checkForm(props);
+
+ // TODO: Finish when the properties are marked read-only.
+
+ }
+ finally {
+ undeployWAR(BASIC_WAR);
+ }
+
+ }
+
+
+
+
+
+ /**
+ * Changes WAR configuration, and verifies that the changes were NOT saved.
+ *
+ * FAILS because some of the values are read-only. EMBJOPR-96
+ */
+ public void testWarConfigurationTabCancel() throws IOException, EmbJoprTestException {
+
+ // Deploy the WAR.
+ String filePath = ejtt.getTestDataDir() +"/war/"+ BASIC_WAR;
+ deployWarRepeatedly( filePath );
+
+ try {
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, BASIC_WAR,
+ DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+ // Navigate to the Configuration tab
+ ContentTableRow row =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+ row.getLinkByLabel(BASIC_WAR).click();
+ ejtt.tabMenu.clickConfigurationTab();
+
+
+ // Load properties (we will use their names).
+ Properties propsToSet = new Properties();
+ String propsFilePath =
ejtt.getTestDataDir()+"/war/"+"war-conf-basic.properties";
+ propsToSet.load(new FileInputStream( propsFilePath ));
+
+ // Get the current properties.
+ Properties propsOriginal = getFormPropertiesValues( propsToSet );
+
+
+ // Set the configuration options and CANCEL
+ fillOutForm( propsToSet );
+ ejtt.getClickableByID("resourceConfigurationForm:cancelButton").click();
+
+
+ // TODO: We should get back to Conf tab automatically: EMBJOPR-100
+ ejtt.tabMenu.clickConfigurationTab();
+
+ // Now check whether the values are the same as before editing.
+ checkForm( propsOriginal );
+
+ }
+ finally {
+ undeployWAR(BASIC_WAR);
+ }
+
+ }
+
+
+
+
+ /**
+ * Redeploys WAR.
+ *
+ * Fails because of: EMBJOPR-109
+ */
+ public void testWarRedeployment() throws IOException, EmbJoprTestException {
+
+ // Deploy the WAR.
+ String appFilePath = ejtt.getTestDataDir() +"/war/"+ BASIC_WAR;
+ deployWarRepeatedly( appFilePath );
+
+ try {
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, BASIC_WAR,
DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+ // Navigate to the Configuration tab
+ ContentTableRow row =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+ row.getLinkByLabel(BASIC_WAR).click();
+ ejtt.tabMenu.clickContentTab();
+
+ String xPath = ".//table//input[@type='file']";
+ HtmlFileInput fileInput =
ejtt.tabMenu.getTabContentBox().getElement().getFirstByXPath(xPath);
+ fileInput.setValueAttribute(appFilePath);
+ xPath = ".//table//input[@type='submit']";
+ HtmlSubmitInput submit =
ejtt.tabMenu.getTabContentBox().getElement().getFirstByXPath(xPath);
+ submit.click();
+
+ }
+ finally {
+ DebugUtils.writeFile("target/redeployment.html",
client.getPageAsText());///
+ undeployWAR(BASIC_WAR);
+ }
+
+ }
+
+
+
+ /**
+ * Deploys exploded WAR and checks whether it is reported as exploded.
+ *
+ * DISABLED - Badly written test, to be fixed. TODO: Hot-deploy
+ */
+ public void DISABLEDtestUnzippedWarReportedAsExploded() throws IOException,
EmbJoprTestException {
+
+ // Deploy the WAR.
+ String WARFilePath = ejtt.getTestDataDir() + "/war/"+BASIC_WAR;
+ deployWarRepeatedly( WARFilePath );
+
+ try {
+ // Wait for WAR to be deployed and UP
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, BASIC_WAR,
DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+ // Click the WAR link
+ ejtt.getTabMenu().getTabContentBox().getFirstTable()
+ .getFirstRowContainingText(BASIC_WAR).getFirstLinkFromColumn("Name").click();
+
+ DebugUtils.writeFile("target/res_traits.html", client.getPageAsText());///
+
+ ContentTable table =
ejtt.getTabMenu().getTabContentBox().getTableUnderHeader("Resource Traits");
+ ContentInfoTable infoTable =
ejtt.getTabMenu().getTabContentBox().getContentInfoTable(table.getElement());
+ Properties props = infoTable.getProperties();
+ log.info("Resource Traits: "+props.toString());
+ log.debug("Exploded?: "+props.getProperty("Exploded?"));
+
+ assertEquals("'Exploded?' should be 'yes'", "yes",
props.getProperty("Exploded?")/*.toLowerCase()*/ );
+
+ }
+ finally {
+ undeployWAR(BASIC_WAR);
+ }
+
+ }
+
+
+
+
+ /**
+ * Checks WAR metrics tab.
+ */
+ public void testWarMetricsTab() throws IOException, EmbJoprTestException {
+
+ // Deploy the WAR.
+ String WARFilePath = ejtt.getTestDataDir() + "/war/"+BASIC_WAR;
+ deployWarRepeatedly( WARFilePath );
+
+ try {
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, BASIC_WAR,
DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+ // Navigate to the Metrics tab
+ ContentTableRow row =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+ row.getLinkByLabel(BASIC_WAR).click();
+ ejtt.tabMenu.clickMetricsTab();
+
+ // Resource Traits
+
+ // Check the Path.
+ HtmlTable tbl = ejtt.getTabMenu().getTabContentBox().
+ getTableUnderHeader("Trait Values").getElement();
+ ContentInfoTable infoTable = ejtt.getContentInfoTable( tbl );
+ Properties props = infoTable.getProperties();
+
+ String path = ejtt.getDeployDir()+"/"+BASIC_WAR;
+ assertEquals(path, props.getProperty("Path").trim());
+
+
+ }
+ finally {
+ undeployWAR(BASIC_WAR);
+ }
+
+ }
+
+
+ /**
+ * Changes WAR configuration, and checks whether the changes were saved.
+ *
+ * FAILS because some of the values are read-only. EMBJOPR-96
+ */
+ public void testWarMetricsTabRefreshButton() throws IOException, EmbJoprTestException,
HtmlElementNotFoundException, Exception {
+
+ // Deploy the WAR.
+ String WARFilePath = ejtt.getTestDataDir() + "/war/"+BASIC_WAR;
+ deployWarRepeatedly( WARFilePath );
+
+ try {
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, BASIC_WAR,
+ DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+ // Navigate to the Metrics tab
+ ContentTableRow row =
ejtt.getDefaultContentTable().getFirstRowContainingLink(BASIC_WAR);
+ row.getLinkByLabel(BASIC_WAR).click();
+ ejtt.tabMenu.clickMetricsTab();
+
+ // Click the Refresh button.
+ // Can this change to submit? Perhaps set an ID and use ejtt.getClickableById().
+ ejtt.tabMenu.getTabContentBox().getButtonByLabel("Refresh").click();
+
+ // Check that we are still on the right tab.
+ assertTrue("Metrics tab is active",
ejtt.tabMenu.isTabActive("Metrics") );
+ assertTrue("Page contains WAR name",
client.getPageAsText().contains(BASIC_WAR) );
+ assertTrue("Page contains 'Refresh'",
client.getPageAsText().contains("Refresh") );
+
+ }
+ finally {
+ undeployWAR(BASIC_WAR);
+ }
+
+ }
+
+
+ /**
+ * Deploys an exploded WAR application.
+ *
+ * FAILS when undeploying, because:
+ *
+org.jboss.jopr.jsfunit.exceptions.EmbJoprTestException: Couldn't delete following
files:
+
/home/ondra/work/JOPRembedded/embjopr-svn-trunk/jsfunit/target/jboss5x/deploy/unpacked-web1.war
+
+ at
org.jboss.jopr.jsfunit.util.EmbJoprTestToolkit$Deployment.deleteDirectory(EmbJoprTestToolkit.java:1662)
+ at
org.jboss.jopr.jsfunit.util.EmbJoprTestToolkit$Deployment.deleteFromDeployDir(EmbJoprTestToolkit.java:1652)
+ at org.jboss.jopr.jsfunit.as5.WarTest.testDeployUnpackedWar(WarTest.java:663)
+ *
+ * TODO: Catch exceptions in finally and log them only (in all tests),
+ * to get the eventual real exception from the try block.
+ *
+ * TODO: Think up how to simulate hot-undeploy.
+ * Should we rename it to other dir and then delete?
+ *
+ * Perhaps it just still didn't process the deployed war when trying to
undeploy?
+ * "Condition 'WAR unpacked-web1.war appears in embjopr as deployed'
not satisfied,
+ * 0 retries left. Leaving the wait loop."
+ * Should we wait more? Or is it caused by failures of some previous tests?
+ *
+ */
+ public void testDeployUnpackedWar() throws IOException, EmbJoprTestException {
+
+
+ // Deploy the unpacked WAR.
+ // We have to use hotdeploy - can't upload a directory.
+ log.info("Unzipping war/"+WAR_UNPACKED_ZIP);
+ ejtt.deployment.unzipToDeployDir("war/"+WAR_UNPACKED_ZIP, "");
+
+ try {
+ // Loop, wait for the app to appear.
+ log.info("Waiting for WAR to appear.");
+ ejtt.deployment.waitActivelyForDeployment(DeployableTypes.WAR, WAR_UNPACKED,
+ DEPLOY_UP_STATE_WAIT_CHECK_INTERVAL, DEPLOY_UP_STATE_WAIT_CHECK_RETRIES, this);
+
+
+ ejtt.getNavTree().getNodeByLabel(NAV_WAR).click();
+
+ ContentTableRow row =
ejtt.getDefaultContentTable().getFirstRowContainingLink(WAR_UNPACKED);
+
+ // TODO: Finish
+
+ // TODO: Check whether Exploded?: yes. EMBJOPR-95
+
+ // TODO: DeploymentUtils, DeployableTypes, isAvailable enum inner classes
+
+ // TODO: Preliminary test - check system properties, their validity, java version,
etc.
+ }
+ finally {
+ // Delete the WAR dir.
+ ejtt.deployment.deleteFromDeployDir(WAR_UNPACKED);
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+ /**
* Deploys WAR.
*/
private void deployWAR( String warFilePath )
@@ -128,28 +723,91 @@
fileInput.setContentType("application/war");
fileInput.setValueAttribute(warFilePath);
client.click("createContentForm:addButton");
+
+ // Log server message.
+ ejtt.logServerMessage();
+
+ // Todo: Write some waitUntilDeployed().
ejtt.sleep( 2000 );
}
+
+ /**
+ * Deploys WAR; if fails, waits 5 seconds and re-tries; this is repeated 3 times.
+ */
+ private void deployWarRepeatedly( final String warFilePath )
+ throws IOException, HtmlElementNotFoundException, EmbJoprTestException
+ {
+
+ try {
+
+ // Try it 3x in 5 second interval.
+ new ActiveConditionChecker( new DescribedCondition("WAR
'"+warFilePath+"' succesfuly deployed") {
+ public boolean isTrue() throws Exception {
+ deployWAR(warFilePath);
+ if( server.getFacesMessages().hasNext() ){
+ FacesMessage msg = server.getFacesMessages().next();
+ if( msg.getSeverity() == FacesMessage.SEVERITY_INFO )
+ return true;
+ else
+ ejtt.logServerMessage("Deployment error: ");
+ }
+ return false;
+ }
+ }).dumpPageOnTimeout(this).throwOnTimeout().waitWithTimeout(5000, 3);
+
+ }
+ catch( Exception ex ){
+ throw new EmbJoprTestException(ex.getMessage());
+ }
+
+
+ }// deployWarRepeatedly()
+
+
+ /**
+ * Undeploys war.
+ *
+ * TODO: When tested, merge to EJTT.Deployment.
+ */
private void undeployWAR( String warFileName )
throws IOException, HtmlElementNotFoundException, ActionNotAvailableException
{
// Navigate to Enterprise Archives
- ejtt.getNavTree().getNodeLink(NAV_EAR).click();
+ ejtt.getNavTree().getNodeLink(NAV_WAR).click();
ejtt.getTabMenu().clickSummaryTab();
- HtmlButtonInput deleteButton = getAppDeleteButton( warFileName );
- deleteButton.click();
+ /// DEBUG dump
+ //String dumpFile = "undeploy"+RandomUtils.nextInt()+".html";
+ //log.debug("Dumping page to: "+dumpFile);
+ //DebugUtils.writeFile(dumpFile, client.getPageAsText());
+ //HtmlButtonInput deleteButton = getAppDeleteButton( warFileName ).click();
+
+ // Find the row containing the deployable. Use the pagination if needed.
+ ContentTableRow appRow = ejtt.getTabMenu().getTabContentBox().
+ findLinkRowInDataTableUsingPagination(warFileName);
+
+ /// DEBUG dump
+ //log.debug("Dumping page to: "+dumpFile+"2");
+ //DebugUtils.writeFile(dumpFile+"2", client.getPageAsText());
+
+ if( null == appRow ){
+ log.warn("Can't find row with WAR to undeploy: "+warFileName);
+ return;
+ }
+
+ appRow.getButtonByLabel("Delete").click();
+
// Log the message (with prefix of potential warning)
ejtt.logServerMessage("Something went wrong with undeploy: ");
- // Sleep for 3 sec. TODO: write some waitForUndeployed()
- ejtt.sleep( 3000 );
+ // Sleep for 3 sec. TODO: write some waitForUndeployed(), as negation of opposite.
+ ejtt.sleep( 2000 );
}
Modified:
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/ActiveConditionChecker.java
===================================================================
---
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/ActiveConditionChecker.java 2009-03-20
03:11:17 UTC (rev 244)
+++
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/ActiveConditionChecker.java 2009-03-20
03:26:13 UTC (rev 245)
@@ -3,6 +3,7 @@
import org.jboss.jopr.jsfunit.*;
import org.apache.commons.lang.StringUtils;
import org.jboss.jopr.jsfunit.exceptions.EmbJoprTestException;
+import org.jboss.jsfunit.jsfsession.JSFClientSession;
import org.jboss.logging.*;
@@ -17,9 +18,12 @@
Condition condition;
private boolean dumpPageOnTimout = false;
private boolean throwExceptionOnTimout = false;
- private EmbjoprTestCase test;
+ // Used when dumping the page in case of exceeded timeout.
+ private String dumpFileName;
+ private JSFClientSession client;
+
public ActiveConditionChecker(Condition condition) {
this.condition = condition;
}
@@ -31,9 +35,20 @@
log.info("Waiting for condition: "+condition.getDescription());
while( retries-- > 0 ){
- if( this.condition.isTrue() )
+ if( this.condition.isTrue() ){
+ log.info(" Condition '"+condition.getDescription()+"'
satisfied.");
return true;
- log.info(" Condition not satisfied, "+retries+" left. Sleeping for
"+msInterval+" ms.");
+ }
+
+ if( retries <= 0){
+ log.info(" Condition '"+condition.getDescription()+"' not
satisfied, "
+ +retries+" retries left. Leaving the wait loop.");
+ break;
+ }
+
+
+ log.info(" Condition '"+condition.getDescription()+"' not
satisfied, "
+ +retries+" retries left. Sleeping for "+msInterval+" ms.");
try {
Thread.sleep(msInterval);
} catch (InterruptedException ex){
@@ -46,7 +61,8 @@
if( this.dumpPageOnTimout ){
try {
// Since this is still inner class, we could use 'this'.
- DebugUtils.writeFile("target/"+test.getName()+".html",
test.getClient().getPageAsText());///
+ log.info("Dumping page text to: "+this.dumpFileName);
+ DebugUtils.writeFile("target/"+this.dumpFileName,
this.client.getPageAsText());///
} catch (Exception ex) { log.error("Can't dump page.", ex); }
}
@@ -67,8 +83,15 @@
// This has nothing to do with condition checking, but is convenient shorthand...
public ActiveConditionChecker dumpPageOnTimeout(EmbjoprTestCase test) {
+ if( null == test ) return this;
+ return dumpPageOnTimeout( test.getName()+".html", test.getClient() );
+ }
+
+ // This has nothing to do with condition checking, but is convenient shorthand...
+ public ActiveConditionChecker dumpPageOnTimeout(String dumpFileName, JSFClientSession
client) {
this.dumpPageOnTimout = true;
- this.test = test;
+ this.dumpFileName = dumpFileName;
+ this.client = client;
return this;
}
Modified: trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/EmbJoprTestToolkit.java
===================================================================
---
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/EmbJoprTestToolkit.java 2009-03-20
03:11:17 UTC (rev 244)
+++
trunk/jsfunit/src/test/java/org/jboss/jopr/jsfunit/util/EmbJoprTestToolkit.java 2009-03-20
03:26:13 UTC (rev 245)
@@ -6,17 +6,27 @@
import com.gargoylesoftware.htmlunit.Page;
import java.util.*;
+import java.util.logging.Level;
import org.jboss.jopr.jsfunit.exceptions.*;
import com.gargoylesoftware.htmlunit.html.*;
import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
import javax.faces.application.FacesMessage;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.jboss.jopr.jsfunit.AppConstants;
+import org.jboss.jopr.jsfunit.AppConstants.DeployableTypes;
+import org.jboss.jopr.jsfunit.DebugUtils;
+import org.jboss.jopr.jsfunit.EmbjoprTestCase;
import org.jboss.jsfunit.jsfsession.*;
import org.jboss.logging.Logger;
import org.mozilla.javascript.NativeFunction;
@@ -385,18 +395,19 @@
*/
public class TabMenu {
- public TabContentBox getTabContentBox() throws HtmlElementNotFoundException {
-
+ public TabContentBox getTabContentBox() throws HtmlElementNotFoundException
+ {
HtmlElement contentElement = (HtmlElement) client.getElement("content");
- HtmlElement tabContentBox = (HtmlElement)
contentElement.getFirstByXPath("div[@class='tabmenubox']");
+ String xPath = "div[@class='tabmenubox' or
@class='notabmenubox']";
+ HtmlElement tabContentBox = (HtmlElement) contentElement.getFirstByXPath(xPath);
if( null == tabContentBox )
- throw new HtmlElementNotFoundException("Tab content box not found using
div[@class='tabmenubox'] XPath");
+ throw new HtmlElementNotFoundException("Tab content box not found using XPath:
"+xPath);
return new TabContentBox(tabContentBox);
}
- public ClickableElement getTabByLabel( String label ) throws
HtmlElementNotFoundException {
-
+ public ClickableElement getTabByLabel( String label ) throws
HtmlElementNotFoundException
+ {
DomElement element = (DomElement)client.getElement("tabmenu");
String xPath =
"ul/li/span[normalize-space(string())='"+label+"'] |
ul/li/a[normalize-space(string())='"+label+"']";
ClickableElement tabContent = element.getFirstByXPath(xPath);
@@ -406,10 +417,10 @@
throw new HtmlElementNotFoundException("Tab '"+label+"' not
found using XPath '"+xPath+"'");
return tabContent;
-
}
- public ClickableElement getTabByID( String tabID ) throws HtmlElementNotFoundException
{
+ public ClickableElement getTabByID( String tabID ) throws HtmlElementNotFoundException
+ {
ClickableElement element = (ClickableElement)client.getElement(tabID);
if( null == element )
throw new HtmlElementNotFoundException("Tab with id
'"+tabID+"' not found, perhaps disabled?");
@@ -536,6 +547,7 @@
+
/**
* Inner class for manipulation with tab content box.
*/
@@ -564,13 +576,18 @@
* Unfortunately, headers are not H2 or similar, but DIV
class="instructionalText".
* To be revised later.
*/
- public ContentTable getTableUnderHeader( String headerText ) throws
ActionOutOfSyncException
+ public ContentTable getTableUnderHeader( String headerText ) throws
ActionOutOfSyncException, HtmlElementNotFoundException
{
checkIfStillValid();
String xPath = "*[contains(normalize-space(),
'"+headerText+"')]/following::table";
// [@id='resourceSummaryForm:dataTable'] - is this reliable?
HtmlTable tableElement = (HtmlTable) element.getFirstByXPath(xPath);
+ if( null == tableElement ){
+ throw new HtmlElementNotFoundException(
+ "Table under header '"+headerText+"' not found using
XPath: "+xPath);
+ }
+
return new ContentTable(tableElement);
}
@@ -637,10 +654,59 @@
}
+ /**
+ * Tries to find a data table row with given deployable, using pagination if needed.
+ * @returns The row wrapper if found, or null.
+ */
+ public ContentTableRow findLinkRowInDataTableUsingPagination(String label)
+ throws HtmlElementNotFoundException, IOException
+ {
+
+ ContentTableRow row = null;
+
+ if( null == getTabMenu().getTabContentBox().getPagination().getPageContols() ){
+ log.debug("No page controls present - that probably means that only single page
is listed.");
+ }
+ else{
+ log.debug("Number of pages:
"+getTabMenu().getTabContentBox().getPagination().getPageCount());
+ }
+
+
+ int currentPage = 1;
+
+ // For all pages...
+ do {
+ HtmlTable tableElm = (HtmlTable)
client.getElement("resourceSummaryForm:dataTable");
+ if( null == tableElm ){
+ throw new HtmlElementNotFoundException(
+ "Data table not found (looking for ID
'resourceSummaryForm:dataTable'");
+ }
+
+ ContentTable table = new ContentTable(tableElm);
+ row = table.findFirstRowContainingText(label);
+
+ // Did we find?
+ if( null != row )
+ break;
+ else
+ log.debug("Row with '"+label+"' not present on page
"+currentPage+".");
+
+ } while (
+ // Infinite loop prevention.
+ currentPage++ < 20
+ // Pagination is not rendered if not needed.
+ && null != getTabMenu().getTabContentBox().getPagination().getPageContols()
+ // goNext() returns true if there's a next page to go.
+ && getTabMenu().getTabContentBox().getPagination().goNext()
+ );
+
+ return row;
+ }
+
+
}// inner class TabContentBox
-
/**
* Contains convenience methods for accessing content tables in EmbJopr.
*/
@@ -656,6 +722,8 @@
* Creates a data table wrapper for the given table element.
*/
public ContentTable( HtmlTable element ) {
+ if( null == element )
+ throw new IllegalArgumentException("null given as element for
ContentTable.");
this.element = element;
}
@@ -708,15 +776,30 @@
// TODO: Escape the single quotes. By doubling?
//
http://books.google.com/books?id=jzqFMlM0gb0C&pg=PA308&lpg=PA308&...
- String xPath = ".//tr[contains(string(), '"+text+"')]";
+ //String xPath = ".//tr[contains(string(), '"+text+"')]";
+ String xPath = ".//tr[.//*[contains(string(),
'"+text+"')]]";
HtmlTableRow elm = (HtmlTableRow) element.getFirstByXPath(xPath);
if( null == elm )
throw new HtmlElementNotFoundException(xPath);
return new ContentTableRow(elm, this);
}
+ /** Same as getFirstRowContainingText(), only returns null if row is not found. */
+ public ContentTableRow findFirstRowContainingText( String text )
+ throws HtmlElementNotFoundException
+ {
+ if( 0 == element.getRowCount() )
+ return null;
+ String xPath = ".//tr[.//*[contains(string(),
'"+text+"')]]";
+ HtmlTableRow elm = (HtmlTableRow) element.getFirstByXPath(xPath);
+ if( null == elm )
+ return null;
+ return new ContentTableRow(elm, this);
+ }
+
+
/**
* Returns wrapper of the table row which contains a link with given label,
* or null when the no such row is found.
@@ -853,19 +936,26 @@
}
/**
- * Parses the content of the table for properties.
- * @return
+ * Parses the content of the table properties.
+ * @returns Set of properties extracted from rows
+ * whose plain text has the 'Name: Value' format.
*/
public Properties getProperties()
{
Properties props = new Properties();
// The template has label in span/strong and the value as text in td.
- String xPath = ".//tr/td[span/strong]";
+ String xPath = ".//tr/td[span/strong | strong]";
+ //String xPath = ".//tr/td[span/strong] | .//tr/td[.//strong]";
List<HtmlTableCell> cells = (List<HtmlTableCell>)
this.getElement().getByXPath(xPath);
for( HtmlTableCell cell : cells ){
- String[] parts = cell.getTextContent().split(":");
- props.put(parts[0], parts[1]);
+ String cellText = cell.getTextContent();
+ String[] parts = cellText.split(":");
+ if( parts.length != 2 ){
+ log.warn("Cell text not in format 'Name: Value': "+cellText);
+ continue;
+ }
+ props.setProperty(parts[0].trim(), parts[1].trim());
}
return props;
}
@@ -906,7 +996,7 @@
public ClickableElement getButtonByLabel( String label ) throws
HtmlElementNotFoundException
{
String xPath = ".//input[@type='button' and normalize-space(@value) =
'"+label+"']" +
- " || .//button[normalize-space() = '"+label+"']";
+ " | .//button[normalize-space() = '"+label+"']";
HtmlElement elm = this.element.getFirstByXPath(xPath);
if( null == elm )
throw new HtmlElementNotFoundException("Can't find the button using xPath:
"+xPath);
@@ -1010,14 +1100,21 @@
private static final String ID_PAGE_SIZE_SELECT =
"categorySummaryForm:currentPageSize";
private static final String ID_PAGINATION_TOTAL_ITEMS =
"paginationTotalItems";
- public HtmlDivision getPageContols(){
- return (HtmlDivision) client.getElement(ID_PAGE_CONTROLS);
+ /** Returns the HTML element of the bar with "First | Prev | 1 2 | Next Last"
controls. */
+ public HtmlDivision getPageContols() throws HtmlElementNotFoundException {
+ //return (HtmlDivision) client.getElement(ID_PAGE_CONTROLS);
+ return (HtmlDivision) getTabMenu().getTabContentBox().getElement()
+ .getFirstByXPath(".//*[contains(@id,
'SummaryForm:dataTableScroller')]");
}
- public HtmlSelect getPageSizeSelect(){
- return (HtmlSelect) client.getElement(ID_PAGE_SIZE_SELECT);
+ /** Returns the HTML Select element of page size selection. */
+ public HtmlSelect getPageSizeSelect() throws HtmlElementNotFoundException {
+ //return (HtmlSelect) client.getElement(ID_PAGE_SIZE_SELECT);
+ return (HtmlSelect) getTabMenu().getTabContentBox().getElement()
+ .getFirstByXPath(".//select[contains(@id,
'SummaryForm:currentPageSize')]");
}
+ /** Returns total items count, taken from the "Total: N" element. */
public int getTotalItemsCount() throws ActionNotAvailableException
{
Element e = client.getElement(ID_PAGINATION_TOTAL_ITEMS);
@@ -1087,7 +1184,7 @@
return !getGoPage(pageNumber).getStyleAttribute().contains("-inact");
}
- public int getPageCount(){
+ public int getPageCount() throws HtmlElementNotFoundException {
String xPath = ".//td[ count(./*) = 0 and normalize-space() > 0 ]";
List<?> elements = getPageContols().getByXPath(xPath);
return elements.size();
@@ -1135,6 +1232,17 @@
public HtmlAnchor getLinkInsideForm(String formId, String linkLabel) throws
HtmlElementNotFoundException
{
HtmlForm form = (HtmlForm)client.getElement(formId);
+ if( null == form ){
+ /// Dump the page
+ String normID = StringUtils.replaceChars(formId, "\\/.: ",
"-----");
+ String dumpFileName = "target/formNotFound-"+ formId +".html";
+ log.debug("Dumping page to file: "+dumpFileName);
+ try { DebugUtils.writeFile(dumpFileName, client.getPageAsText()); }
+ catch (Exception ex) { log.warn("getLinkInsideForm(): "+ ex.toString()); }
+
+ throw new HtmlElementNotFoundException("Form element of given ID not found:
"+formId);
+ }
+
String xPath = ".//a[contains(normalize-space(),
'"+linkLabel+"')]";
HtmlAnchor link = form.getFirstByXPath(xPath);
if( null == link )
@@ -1147,11 +1255,12 @@
/** Calls Thread.sleep(ms), ignores the InterruptedException. */
@SuppressWarnings("empty-statement")
- public static void sleep( int ms ) {
+ public void sleep( int ms ) {
try {
- Thread.sleep(3000);
+ Thread.sleep(ms);
} catch (InterruptedException ex) {
- ; // We don't care, that's the purpose of this method.
+ log.warn("EJTT.sleep() interrupted.");
+ // We don't care more, that's the purpose of this method.
}
}
@@ -1224,26 +1333,16 @@
}
+ public final Deployment deployment = new Deployment();
public class Deployment {
// TODO: Shortcuts:
/*
- private void deployWAR( String warFilePath ){
-
- }
-
- private void undeployWAR( String warFileName ){
-
- }
-
- private void deployEAR( String warFilePath ){
-
- }
-
- private void undeployEAR( String warFileName ){
-
- }
+ private void deployWAR( String warFilePath ){}
+ private void undeployWAR( String warFileName ){}
+ private void deployEAR( String warFilePath ){}
+ private void undeployEAR( String warFileName ){}
// Etc. */
@@ -1253,7 +1352,7 @@
*
* @param type Type of the deployable - EAR, SAR, WAR, ...
*/
- private void deployViaEmbJopr( AppConstants.DeployableTypes type, String filePath )
+ public void deployViaEmbJopr( AppConstants.DeployableTypes type, String filePath )
throws IOException, HtmlElementNotFoundException
{
if( !(new File(filePath)).exists())
@@ -1283,7 +1382,7 @@
*
* @param type Type of the deployable - EAR, SAR, WAR, ...
*/
- private void undeployViaEmbJopr( AppConstants.DeployableTypes type, String fileName )
+ public void undeployViaEmbJopr( AppConstants.DeployableTypes type, String fileName )
throws IOException, HtmlElementNotFoundException, ActionNotAvailableException,
ActionOutOfSyncException
{
@@ -1306,12 +1405,292 @@
}// undeployViaEmbJopr()
- }
+ // TODO: The following was copied from EarTest.java; remove from there.
+ /** Convenience method, setting mustBeUP to true. */
+ public boolean isDeployedAccordingToEmbJopr( DeployableTypes type, String
deployableName )
+ throws HtmlElementNotFoundException, IOException, ActionNotAvailableException{
+ return isDeployedAccordingToEmbJopr( type, deployableName, true );
+ }
+ /**
+ * Returns true if EmbJopr lists a deployable of given type and name,
+ * and it's State is UP; false otherwise.
+ */
+ public boolean isDeployedAccordingToEmbJopr(
+ DeployableTypes type, String deployableName, boolean mustBeUP )
+ throws HtmlElementNotFoundException, IOException, ActionNotAvailableException
+ {
+ // Refresh / go to the appropriate page.
+ getNavTree().getNodeByLabel( type.getNavTreeLabel() ).click();
+ // Pagination
+ //int totalItemsCount =
getTabMenu().getTabContentBox().getPagination().getTotalItemsCount();
+
+ /*
+ ContentTableRow appRow = null;
+
+ // Search trough all pages.
+ int currentPage = 1;
+ do {
+ appRow = getDefaultContentTable().findFirstRowContainingLink(deployableName);
+ if( null != appRow ){
+ break;
+ }else{
+ log.debug("Row with "+deployableName+" not present on page
"+currentPage+".");
+ }
+ } while( currentPage++ < 20 &&
getTabMenu().getTabContentBox().getPagination().goNext() );
+
+ */
+
+ // Find the row containing the deployable. Use the pagination if needed.
+ ContentTableRow appRow = getTabMenu().getTabContentBox().
+ findLinkRowInDataTableUsingPagination(deployableName);
+
+ if( null == appRow ){
+ log.debug("Row with '"+deployableName+"' not found.");
+ return false;
+ }
+
+ if( !mustBeUP ){
+ // Not needed to be UP; we found it, thus return true.
+ return true;
+ }
+
+ String statusText = appRow.getCellTextByColumnName("Status");
+ if( "UP".equals(statusText) ){
+ return true;
+ }else{
+ log.debug("Row with "+deployableName+" has Status ==
'"+statusText+"' != UP.");
+ return false;
+ }
+
+ }// isDeployedAccordingToEmbJopr()
+
+
+
+ /**
+ * Waits for the deployable to be in the UP State.
+ *
+ * @param type Type of deployable - EAR, WAR, SAR, ...
+ * @param name Name of the deployable, like 'hello.war'.
+ */
+ public void waitActivelyForDeployment(
+ final DeployableTypes type, final String name,
+ int intervalMS, int retries
+ )
+ throws EmbJoprTestException, IOException
+ {
+ waitActivelyForDeployment(type, name, intervalMS, retries, null);
+ }
+
+ /**
+ * Waits for the deployable to be in the UP State.
+ *
+ * @param type Type of deployable - EAR, WAR, SAR, ...
+ * @param name Name of the deployable, like 'hello.war'.
+ */
+ public void waitActivelyForDeployment(
+ final DeployableTypes type, final String name,
+ int intervalMS, int retries,
+ EmbjoprTestCase test // used for page dump
+ )
+ throws EmbJoprTestException, IOException
+ {
+ try {
+ //final EmbJoprTestToolkit selfEjtt = getEjtt();
+
+ String conditionDesc = type.name()+" "+name+" appears in embjopr as
deployed";
+ ActiveConditionChecker checker =
+ new ActiveConditionChecker(new DescribedCondition(conditionDesc) {
+
+ int callsMade = 0;
+
+ public boolean isTrue() throws HtmlElementNotFoundException, IOException,
ActionNotAvailableException {
+ // Refresh the page if this is not the first call.
+ if (callsMade++ > 0) {
+ selfEjtt.refreshPage();
+ }
+ // If found, return true.
+ return isDeployedAccordingToEmbJopr(type, name);
+ // If found, return true.
+ }
+ }).throwOnTimeout();
+
+ if( null != test )
+ checker.dumpPageOnTimeout(test);
+
+ boolean deployedSuccessfuly = checker.waitWithTimeout( intervalMS, retries );
+ }
+ catch( EmbJoprTestException ex ){ throw ex; }
+ catch( IOException ex ){ throw ex; }
+ // Wrap all exceptions to EmbJoprTestException.
+ catch( Exception ex ){
+ throw new EmbJoprTestException("Exception thrown while actively waiting for
condition.", ex);
+ }
+ }
+
+
+
+ /**
+ * Returns true if there's a file of the given name in server's deploy dir;
+ * false otherwise.
+ */
+ private boolean isDeployedAccordingToFileSystem( DeployableTypes type, String name )
+ {
+ String deployPath = getDeployDir();
+ String fileName = deployPath+"/"+name;
+ return (new File(fileName)).exists();
+ }
+
+ private void undeployViaFileSystem( String name ) throws EmbJoprTestException{
+ String deployPath = getDeployDir();
+ String fileName = deployPath+"/"+name;
+ File fileToDelete = new File(fileName);
+
+ if( !fileToDelete.exists() )
+ throw new EmbJoprTestException("Deployable doesn't exist: "+fileName);
+
+ if(fileToDelete.isFile()){
+ if( !fileToDelete.delete() ){
+ throw new EmbJoprTestException("Unable to delete: "+fileName);
+ }
+ }else if(fileToDelete.isDirectory()){
+ deleteDirectory(fileToDelete);
+ }
+
+ }// isDeployedAccordingToFileSystem()
+
+
+
+ /**
+ * Unzips given archive from testdata dir to server's deploy/ dir.
+ * @param relativeArchivePath Path of the archive relative to testdata dir.
+ * @param relativeDestDir Path of the destination dir relative to deploy dir.
+ */
+ public void unzipToDeployDir( String relativeArchivePath, String relativeDestDir )
+ throws FileNotFoundException, IOException
+ {
+
+ String destDir = getTestDataDir()+"/"+relativeDestDir;
+ String archivePath = getTestDataDir()+"/"+relativeArchivePath;
+
+ log.info("Unzipping '"+archivePath+"' to
'"+destDir+"'.");
+
+ unzipArchive( archivePath, destDir );
+ }
+
+
+
+ /**
+ * Unzips archive from the given path to the given destination dir.
+ */
+ public void unzipArchive(String archivePath, String destDir)
+ throws FileNotFoundException, IOException
+ {
+
+ FileInputStream fis = new FileInputStream( archivePath );
+ ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis));
+
+ ZipEntry entry;
+ while( null != (entry = zin.getNextEntry()) ){
+
+ if(entry.isDirectory()) {
+ // Assume directories are stored parents first then children.
+ log.info("Extracting directory: " + entry.getName());
+ // This is not robust, just for demonstration purposes.
+ (new File(destDir +"/"+ entry.getName())).mkdir();
+ continue;
+ }
+
+ log.info("Extracting file: " + entry.getName());
+
+ final int BUFFER = 2048;
+ FileOutputStream fos = new FileOutputStream( destDir +"/"+
entry.getName());
+ BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
+
+ int count;
+ byte[] data = new byte[BUFFER];
+ while ((count = zin.read(data, 0, BUFFER)) != -1) {
+ dest.write(data, 0, count);
+ }
+ dest.flush();
+ dest.close();
+ zin.closeEntry();
+
+ }
+
+ zin.close();
+
+ }
+
+
+
+
+ public void deleteFromDeployDir( String deployableName ) throws IOException,
EmbJoprTestException{
+
+ String deployDir = getDeployDir();
+
+ File dirToDelete = new File( deployDir, deployableName);
+
+ // Just not to delete something accidentally...
+ // For tests:
+ // /.../embjopr-svn-trunk/jsfunit/target/jboss5x/deploy/unpacked-web1.war.zip
+ /*if( ! dirToDelete.getCanonicalPath().contains("/server/") )
+ throw new EmbJoprTestException( "Path to deployable doesn't contain
'/server/': "
+ +dirToDelete.getCanonicalPath() );
+ /**/
+
+ // Check if not outside deploy dir.
+ if( !dirToDelete.getCanonicalPath().startsWith( deployDir ) )
+ throw new IllegalArgumentException(
+ " The resulting path is outside deploy dir:
"+dirToDelete.getCanonicalPath());
+
+ log.info("Deleting '"+dirToDelete.getPath()+"'...");
+ deleteDirectory( dirToDelete );
+ }
+
+
+
+ public /*static*/ void deleteDirectory(File path) throws EmbJoprTestException
+ {
+ List<String> undeletableFiles = new ArrayList();
+ deleteDirectory(path, undeletableFiles);
+ if( !undeletableFiles.isEmpty() ){
+ throw new EmbJoprTestException("Couldn't delete following files: \n
"+
+ StringUtils.join(undeletableFiles, "\n ") + "\n");
+ }
+ }
+
+ public /*static*/ void deleteDirectory(File path, List<String> undeletableFiles)
+ {
+ if( path.exists() ) {
+ File[] files = path.listFiles();
+ for(int i=0; i<files.length; i++) {
+ if(files[i].isDirectory()) {
+ deleteDirectory(files[i], undeletableFiles );
+ }
+ else {
+ if( !files[i].delete() ){
+ undeletableFiles.add(files[i].getAbsolutePath());
+ }
+ }
+ }
+ }
+ if( ! path.delete() )
+ undeletableFiles.add( path.getAbsolutePath() );
+ }
+
+
+ }// class Deployment
+
+
+
+
+
+
// TODO
protected class JMXDeploymentInfo {