Author: mstruk
Date: 2011-03-21 18:17:27 -0400 (Mon, 21 Mar 2011)
New Revision: 6105
Modified:
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/AbstractWebTest.java
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/common/WebHelper.java
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/jira/Test_GTNPORTAL_1823_FailToCreatePage.java
Log:
GTNPORTAL-1823 Fail to create one page when creating two new pages at the same time.
- Test case to reproduce the issue
Modified:
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/AbstractWebTest.java
===================================================================
---
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/AbstractWebTest.java 2011-03-18
16:49:53 UTC (rev 6104)
+++
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/AbstractWebTest.java 2011-03-21
22:17:27 UTC (rev 6105)
@@ -133,11 +133,11 @@
}
/**
- * @see WebHelper#waitForTextPresent(String)
+ * @see WebHelper#waitForTextPresent(String ...)
*/
- protected void waitForTextPresent(String text)
+ protected String waitForTextPresent(String ... text)
{
- getWebHelper().waitForTextPresent(text);
+ return getWebHelper().waitForTextPresent(text);
}
/**
@@ -195,4 +195,40 @@
{
getWebHelper().addNewPageUpToFinish(categoryTitle, portletName, pageName,
portletElementToDnD);
}
+
+ protected void goToPageManagement()
+ {
+ getWebHelper().goToPageManagement();
+ }
+
+ protected void searchAndDeletePage(String testPage)
+ {
+ getWebHelper().searchAndDeletePage(testPage);
+ }
+
+ protected void goToSiteManagement()
+ {
+ getWebHelper().goToSiteManagement();
+ }
+
+ protected void editNavigation(String portalContainer)
+ {
+ getWebHelper().editNavigation(portalContainer);
+ }
+
+ protected void deleteNode(String nodeLabel)
+ {
+ getWebHelper().deleteNode(nodeLabel);
+ }
+
+ protected void leavePageEdit()
+ {
+ getWebHelper().leavePageEdit();
+ }
+
+ protected void finished()
+ {
+ if (getWebHelper().isDumpPageOnExit())
+ getWebHelper().dumpPage();
+ }
}
Modified:
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/common/WebHelper.java
===================================================================
---
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/common/WebHelper.java 2011-03-18
16:49:53 UTC (rev 6104)
+++
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/common/WebHelper.java 2011-03-21
22:17:27 UTC (rev 6105)
@@ -22,13 +22,24 @@
package org.jboss.gatein.htmlunit.common;
+import com.gargoylesoftware.htmlunit.ConfirmHandler;
+import com.gargoylesoftware.htmlunit.IncorrectnessListener;
+import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.html.HTMLParserListener;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
+import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.html.HtmlSelect;
+import org.apache.commons.logging.LogFactory;
import org.testng.Assert;
+import org.testng.log4testng.Logger;
import java.io.IOException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Properties;
/**
* WebHelper class contains helper methods to easily perform GateIn portal operations
@@ -37,6 +48,7 @@
*/
public class WebHelper
{
+
/** HTMLUnit Webclient represents a web session */
private WebClient webClient;
@@ -52,14 +64,107 @@
/** Time to wait (in seconds) for element or text to appear in the page */
private int waitTimeout = 20;
- /** Short pause period (in seconds)*/
+ /** Short pause period (in seconds) */
private int shortPause = 3;
+ /** Dump current page before throwing exception */
+ private boolean dumpPageOnFail = false;
+
+ /** Dump current page on exit */
+ private boolean dumpPageOnExit = false;
+
+ /** Properties to use for configuration overrides */
+ private Properties props = System.getProperties();
+
/** Current page */
private HtmlPage page;
- /** Get HTMLUnit WebClient instance representing the current session */
+ /**
+ * Get host property.
+ *
+ * @return value of host property
+ */
+ public String getHost()
+ {
+ return host;
+ }
+
+ /**
+ * Get port property.
+ *
+ * @return value of port property
+ */
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * Get portalContainer property.
+ *
+ * @return value of portalContainer property
+ */
+ public String getPortalContainer()
+ {
+ return portalContainer;
+ }
+
+ /**
+ * Get properties used for initialization.
+ *
+ * @return Properties
+ */
+ public Properties getProps()
+ {
+ return props;
+ }
+
+ /**
+ * Get shortPause property.
+ *
+ * @return value of shortPause property
+ */
+ public int getShortPause()
+ {
+ return shortPause;
+ }
+
+ /**
+ * Get waitTimeout property.
+ *
+ * @return value of waitTimeout property
+ */
+ public int getWaitTimeout()
+ {
+ return waitTimeout;
+ }
+
+ /**
+ * Is dumpPageOnFail flag true.
+ *
+ * @return value of dumpPageOnFail property
+ */
+ public boolean isDumpPageOnFail()
+ {
+ return dumpPageOnFail;
+ }
+
+ /**
+ * Is dumpPageOnExit flag true.
+ *
+ * @return value of dumpPageOnExit property
+ */
+ public boolean isDumpPageOnExit()
+ {
+ return dumpPageOnExit;
+ }
+
+ /**
+ * Get HTMLUnit WebClient instance representing the current session.
+ *
+ * @return WebClient instance representing a browser window
+ */
public WebClient getWebClient()
{
if (webClient == null)
@@ -68,32 +173,113 @@
webClient.setThrowExceptionOnFailingStatusCode(false);
webClient.setThrowExceptionOnScriptError(false);
- initFromSystemProps();
+/*
+ //
+ // all this seems to have no effect on logging
+ //
+
+ webClient.setHTMLParserListener(new HTMLParserListener()
+ {
+ public void error(String message, URL url, int line, int column, String key)
+ {
+
+ }
+
+ public void warning(String message, URL url, int line, int column, String
key)
+ {
+
+ }
+ });
+ webClient.setIncorrectnessListener(new IncorrectnessListener() {
+ public void notify(String message, Object origin)
+ {
+
+ }
+ });
+
+ LogFactory.getFactory().setAttribute("org.apache.commons.logging.Log",
"org.apache.commons.logging.impl.SimpleLog");
+
+ System.setProperty("org.apache.commons.logging.simplelog.defaultlog",
"fatal");
+
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http",
"debug");
+*/
+
+ initFromProps();
}
return webClient;
}
- private void initFromSystemProps()
+ /**
+ * Get current page.
+ *
+ * @return current page
+ */
+ public HtmlPage getPage()
{
- String val = System.getProperty("test.host");
+ return page;
+ }
+
+ /**
+ * Properties object containing configuration overrides.
+ *
+ * @return properties object
+ */
+ public Properties getProperties()
+ {
+ return props;
+ }
+
+ /**
+ * Set configuration overrides.
+ *
+ * @param props Properties object containing configuration overrides
+ */
+ public void setProperties(Properties props)
+ {
+ if (props == null)
+ throw new IllegalArgumentException("Null properties");
+ this.props = props;
+ }
+
+ /**
+ * Initialize from properties.
+ */
+ private void initFromProps()
+ {
+ String val = props.getProperty("test.host");
if (val != null)
host = val;
- val = System.getProperty("test.port");
+ val = props.getProperty("test.port");
if (val != null)
port = Integer.parseInt(val);
- val = System.getProperty("test.portalContainer");
+ val = props.getProperty("test.portalContainer");
if (val != null)
portalContainer = val;
- val = System.getProperty("test.waitTimeout");
+ val = props.getProperty("test.waitTimeout");
if (val != null)
waitTimeout = Integer.parseInt(val);
- val = System.getProperty("test.shortPause");
+ val = props.getProperty("test.shortPause");
if (val != null)
shortPause = Integer.parseInt(val);
+
+ val = props.getProperty("test.dumpPageOnFail");
+ if (val != null)
+ dumpPageOnFail = Boolean.parseBoolean(val);
+
+ val = props.getProperty("test.dumpPageOnExit");
+ if (val != null)
+ dumpPageOnExit = Boolean.parseBoolean(val);
+
+ log("Initial properties:\n\thost: " + host
+ + "\n\tport: " + port
+ + "\n\tportalContainer: " + portalContainer
+ + "\n\twaitTimeout: " + waitTimeout
+ + "\n\tshortPause: " + shortPause
+ + "\n\tdumpPageOnFail: " + dumpPageOnFail
+ + "\n\tdumpPageOnExit: " + dumpPageOnExit);
}
/**
@@ -104,26 +290,41 @@
*/
public void openPortal(boolean publicMode) throws IOException
{
- System.out.println("--Open portal home--");
+ log("--Open portal home--");
page = getWebClient().getPage(getStartUrl(publicMode));
HtmlElement desc = page.getFirstByXPath(".//div[contains(text(), 'All
rights reserved')]");
if (desc == null)
throw new RuntimeException("Portal page content corrupted\r\n" +
page.asText());
}
+ /**
+ * Compose portal's home page url.
+ *
+ * @param publicMode
+ * @return
+ */
private String getStartUrl(boolean publicMode)
{
return "http://" + host + ":" + port + "/" +
portalContainer + "/" + (publicMode ? "public" :
"private");
}
+ /**
+ * Sign in as root.
+ */
public void signInAsRoot()
{
signIn("root", "gtn");
}
+ /**
+ * Sign in with username and password.
+ *
+ * @param user username
+ * @param pass password
+ */
public void signIn(String user, String pass)
{
- System.out.println("--Sign in as " + user + "--");
+ log("--Sign in as " + user + "--");
waitForElementPresent("link=Sign in");
click("link=Sign in");
waitForElementPresent("username");
@@ -134,7 +335,7 @@
}
/**
- * Fill form field with text
+ * Fill form field with text.
*
* @param field
* @param value
@@ -149,7 +350,7 @@
}
/**
- * Simulate clicking an element in the page
+ * Simulate clicking an element in the page.
*
* @param el expression identifying an element
*/
@@ -166,12 +367,20 @@
}
}
+ /**
+ * Wait for element to be present in the current page,
+ * for a maximum time determined by <tt>waitSeconds</tt> property.
+ *
+ * @param el element specification
+ */
public void waitForElementPresent(String el)
{
for (int second = 0; ; second++)
{
if (second >= waitTimeout)
{
+ if (dumpPageOnFail)
+ dumpPage();
Assert.fail("Timeout at waitForElementPresent: " + el);
}
if (isElementPresent(el))
@@ -182,19 +391,96 @@
}
}
+ /**
+ * Wait for element to not be present any more in the current page,
+ * for a maximum time determined by <tt>waitSeconds</tt> property.
+ *
+ * @param el element specification
+ */
+ public void waitForElementNotPresent(String el)
+ {
+ for (int second = 0; ; second++)
+ {
+ if (second >= waitTimeout)
+ {
+ if (dumpPageOnFail)
+ dumpPage();
+ Assert.fail("Timeout at waitForElementPresent: " + el);
+ }
+ if (!isElementPresent(el))
+ {
+ break;
+ }
+ pause(1000);
+ }
+ }
+
+ /**
+ * Check if specified element is present in current page.
+ *
+ * @param el element specification
+ * @return true if present
+ */
public boolean isElementPresent(String el)
{
HtmlElement node = getElement(el);
return node != null;
}
+ /**
+ * Get first occurence of specified element in current page.
+ *
+ * <p>
+ * Element specification can have one of several forms:
+ * <ul>
+ * <li>link=<em>link-text</em> - matches the first %lt;a>
element with specified link-text</li>
+ * <li>xpath=<em>xpath-query</em> - matches the first element
that the specified xpath query returns</li>
+ * <li>//<em>xpath-query</em> - matches the first element that
the specified xpath query returns</li>
+ * <li><em>name-id</em> - matches the first element with id or
name attribute equal to <em>name-id</em></li>
+ * </ul>
+ *
+ * @param el element specification
+ * @return element if present, null otherwise
+ */
public HtmlElement getElement(String el)
{
+ // it seems that page state is often changing at the time we call getElement()
+ // which causes concurrency issues and results in RuntimeExceptions
+ RuntimeException e = null;
+ for (int i=0; i<3; i++)
+ {
+ try
+ {
+ return _getElement(el);
+ }
+ catch (RuntimeException ex)
+ {
+ e = ex;
+ try
+ {
+ Thread.sleep(1000);
+ }
+ catch(InterruptedException ex2)
+ {
+ throw new RuntimeException("Interrupted!");
+ }
+ }
+ }
+ throw e;
+ }
+
+ private HtmlElement _getElement(String el)
+ {
if (el.startsWith("link="))
{
String xpath = convertFromLinkElSpec(el);
return page.getFirstByXPath(xpath);
}
+ else if (el.startsWith("xpath="))
+ {
+ String xpath = convertFromXPathElSpec(el);
+ return page.getFirstByXPath(xpath);
+ }
else if (el.startsWith("//"))
{
return page.getFirstByXPath(el);
@@ -205,6 +491,13 @@
}
}
+ private String convertFromXPathElSpec(String el)
+ {
+ if (el.startsWith("xpath="))
+ el = el.substring(6);
+ return el;
+ }
+
private String convertFromLinkElSpec(String el)
{
if (el.startsWith("link="))
@@ -212,29 +505,47 @@
return ".//a[text() = '" + el + "']";
}
- public void waitForTextPresent(String text)
+ public String waitForTextPresent(String ... text)
{
for (int second = 0; ; second++)
{
if (second >= waitTimeout)
{
- //System.out.println("[DEBUG] " + page.asXml());
- Assert.fail("Timeout at waitForTextPresent: " + text);
+ if (dumpPageOnFail)
+ dumpPage();
+ Assert.fail("Timeout at waitForTextPresent: " +
Arrays.asList(text));
}
- if (isTextPresent(text))
+ String found = getTextPresent(text);
+ if (found != null)
{
- break;
+ return found;
}
pause(1000);
}
}
+ /**
+ * Dump the current page as XML
+ */
+ public void dumpPage()
+ {
+ log("Page dump: " + page.asXml());
+ }
+
+ /**
+ * Wait for text to not be present any more in the current page,
+ * for a maximum time determined by <tt>waitSeconds</tt> property.
+ *
+ * @param text text to not be present any more
+ */
public void waitForTextNotPresent(String text)
{
for (int second = 0; ; second++)
{
if (second >= waitTimeout)
{
+ if (dumpPageOnFail)
+ dumpPage();
Assert.fail("Timeout at waitForTextPresent: " + text);
}
if (isTextPresent(text) == false)
@@ -245,16 +556,68 @@
}
}
+ /**
+ * Check if specified text is present
+ *
+ * @param text
+ * @return true if text is present
+ */
public boolean isTextPresent(String text)
{
- return page.asText().indexOf(text) > -1;
+ try
+ {
+ return page.asText().indexOf(text) > -1;
+ }
+ catch (Exception e)
+ {
+ shortPause();
+ return page.asText().indexOf(text) > -1;
+ }
}
+ /**
+ * Check if any of the passed arguments is present as text in the page.
+ * When any is encountered it is returned.
+ *
+ * @param text string items to check for presence
+ * @return found item or null of none of the items is present
+ */
+ public String getTextPresent(String ... text)
+ {
+ String pageText;
+
+ try
+ {
+ pageText = page.asText();
+ }
+ catch (Exception e)
+ {
+ shortPause();
+ pageText = page.asText();
+ }
+
+ for (String item: text)
+ {
+ if (pageText.indexOf(item) != -1)
+ return item;
+ }
+
+ return null;
+ }
+
+ /**
+ * Pause for a few seconds - length controlled by shortPause property
+ */
public void shortPause()
{
pause(shortPause * 1000);
}
+ /**
+ * Pause for a specified number of millis
+ *
+ * @param millis
+ */
public static void pause(long millis)
{
try
@@ -275,7 +638,7 @@
*/
public void dragAndDropToObject(String sourceEl, String targetEl)
{
- System.out.println("--Drag and drop to object--");
+ log("--Drag and drop to object--");
HtmlElement src = getElement(sourceEl);
if (src == null)
throw new RuntimeException("No source element: " + sourceEl);
@@ -295,7 +658,7 @@
*/
public void finishPageEdit()
{
- System.out.println("--Finish Page Edit--");
+ log("--Finish Page Edit--");
waitForElementPresent("//div[@id='UIPageEditor']/div[1]/div/div/div/a[2]");
click("//div[@id='UIPageEditor']/div[1]/div/div/div/a[2]");
waitForTextNotPresent("Page Editor");
@@ -312,7 +675,7 @@
*/
public void addNewPageUpToFinish(String categoryTitle, String portletName, String
pageName, String portletElementToDnD)
{
- System.out.println("--Add new page up to Finish--");
+ log("--Add new page up to Finish--");
waitForElementPresent("link=Add New Page");
click("link=Add New Page");
@@ -334,4 +697,161 @@
}
}
+ public void goToPageManagement()
+ {
+ log("--Go to Page Management--");
+ waitForElementPresent("link=Page Management");
+ click("link=Page Management");
+ //waitForPageToLoad(); // no need for this - we're synchronous
+ }
+
+ public void searchAndDeletePage(String title)
+ {
+ searchPageByTitle(title, null);
+ deletePage(title, false, null);
+ }
+
+ public void setupConfirmation(final String text)
+ {
+ webClient.setConfirmHandler(new ConfirmHandler()
+ {
+ public boolean handleConfirm(Page page, String message)
+ {
+ if (text.equals(message))
+ {
+ return true;
+ }
+ else
+ throw new RuntimeException("Unexpected message: " + message);
+ }
+ });
+ }
+
+ public void resetConfirmation()
+ {
+ webClient.setConfirmHandler(null);
+ }
+
+ private void deletePage(String title, boolean closeDialog, String verifyText)
+ {
+ log("--Delete page: " + title + "--");
+ String delButton =
"//tbody[@class='FeedBox']//tr[*/div[@title='" + title +
"']]//img[@title='Delete Page' and contains(@onclick,
'op=Delete')]";
+ waitForElementPresent(delButton);
+
+ setupConfirmation("Do you want to delete this page?");
+ click(delButton);
+ resetConfirmation();
+
+ if (verifyText != null)
+ {
+ waitForTextNotPresent(verifyText);
+ }
+ //if (closeDialog)
+ //{
+ // closeMessageDialog();
+ //}
+ }
+
+ public void searchPageByTitle(String title, String verifyText)
+ {
+ log("--Searching page: " + title + "--");
+ waitForElementPresent("searchTerm");
+ type("searchTerm", title);
+ select("searchOption", "label=Title");
+
waitForElementPresent("xpath=//form[@id='UIPageSearch']/div[2]/a");
+ click("xpath=//form[@id='UIPageSearch']/div[2]/a");
+ shortPause();
+ if (verifyText != null)
+ {
+ waitForTextPresent(verifyText);
+ }
+ }
+
+ private void select(String selectEl, String select)
+ {
+ HtmlElement el = getElement(selectEl);
+ if (el instanceof HtmlSelect)
+ {
+ // find SelectOption
+ HtmlSelect sel = (HtmlSelect) el;
+ HtmlOption opt = null;
+
+ if (select.startsWith("label=") || select.indexOf("=") ==
-1)
+ {
+ String label = select.substring(6);
+ opt = sel.getOptionByText(label);
+ if (opt == null)
+ throw new RuntimeException("No such option (" + label + ")
for Select Input " + selectEl);
+ page = (HtmlPage) sel.setSelectedAttribute(opt, true);
+ }
+ else
+ {
+ throw new RuntimeException("Unsupported options specification format:
" + select);
+ }
+ }
+ else
+ {
+ throw new RuntimeException("Specified element not of type HtmlSelect
(" + selectEl + "): " + el);
+ }
+ }
+
+ public void goToSiteManagement()
+ {
+ log("--Go to Page Management--");
+ waitForElementPresent("link=Page Management");
+ click("link=Page Management");
+ }
+
+ public void editNavigation(String site)
+ {
+ log("--Edit Navigation : " + site + "--");
+ String navLink = "//table[@class='ManagementBlock' and
//tr/td/div/text() = '"
+ + site + "']//a[text() = 'Edit Navigation']";
+ waitForElementPresent(navLink);
+ click(navLink);
+ waitForElementPresent("link=Add Node");
+ }
+
+ public void deleteNode(String nodeLabel)
+ {
+ log("--Deleting node from navigation--");
+ waitForElementPresent("//a[@title='" + nodeLabel +
"']");
+ shortPause();
+ contextMenuOnElement("//a[@title='" + nodeLabel +
"']");
+ shortPause();
+
waitForElementPresent("//div[@id='UINavigationNodeSelector']//div[@id='NavigationNodePopupMenu']//a[@class='ItemIcon
DeleteNode16x16Icon']");
+ setupConfirmation("Are you sure you want to delete this node?");
+
click("//div[@id='UINavigationNodeSelector']//div[@id='NavigationNodePopupMenu']//a[@class='ItemIcon
DeleteNode16x16Icon']");
+ resetConfirmation();
+ waitForElementNotPresent("//a[@title='" + nodeLabel +
"']");
+ waitForElementPresent("link=Save");
+ click("link=Save");
+ waitForTextNotPresent("Navigation Management");
+ waitForTextNotPresent(nodeLabel);
+ }
+
+ public void contextMenuOnElement(String element)
+ {
+ String source = "selenium.doComponentExoContextMenu(\"" + element +
"\")";
+ webClient.getJavaScriptEngine().execute(page, source, "script", 1);
+ }
+
+ public void leavePageEdit()
+ {
+ log("-- Leave PageEdit --");
+ // we could have an error window popped up
+ String closeButton = "//div[@class='ExoMessageDecorator' and
//div[@class='TabsContainer']//div[@class='SelectedTab']]//div[@class='CloseButton']";
+ click(closeButton);
+
+ // also we may have to abort
+ String abortButton =
"//table[@class='ActionContainer']//div[contains(@onclick,
'action=Abort')]//a[text()='Abort']";
+ click(abortButton);
+
+ waitForTextNotPresent("Page Editor");
+ }
+
+ public void log(String msg)
+ {
+ System.out.println(msg);
+ }
}
Modified:
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/jira/Test_GTNPORTAL_1823_FailToCreatePage.java
===================================================================
---
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/jira/Test_GTNPORTAL_1823_FailToCreatePage.java 2011-03-18
16:49:53 UTC (rev 6104)
+++
portal/trunk/testsuite/htmlunit-tests/src/test/java/org/jboss/gatein/htmlunit/jira/Test_GTNPORTAL_1823_FailToCreatePage.java 2011-03-21
22:17:27 UTC (rev 6105)
@@ -23,8 +23,11 @@
package org.jboss.gatein.htmlunit.jira;
import org.jboss.gatein.htmlunit.AbstractWebTest;
+import org.testng.Assert;
import org.testng.annotations.Test;
+import org.testng.log4testng.Logger;
+import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
@@ -33,6 +36,9 @@
*/
public class Test_GTNPORTAL_1823_FailToCreatePage extends AbstractWebTest
{
+ /** Logger */
+ private static final Logger log =
Logger.getLogger(Test_GTNPORTAL_1823_FailToCreatePage.class);
+
/** Number of concurrent threads for the test */
private static final int TCOUNT = 2;
@@ -81,26 +87,127 @@
private void test() throws Throwable
{
String id = nextId();
+ String categoryTitle = "Gadgets";
+ String portletName = "Calculator";
+ String pageName = "TestPage" + id;
+ String portletElementToDnD = "//div[@id='" + categoryTitle +
"/" + portletName + "']";
openPortal(true);
+ // Check that testPage with this name does not yet exist
+ Assert.assertFalse(isElementPresent("link=" + pageName), "Page
exists already: " + pageName);
+
signInAsRoot();
// Add new page, but don't click Finish yet at the end
- String categoryTitle = "Gadgets";
- String portletName = "Calculator";
- String pageName = "TestPage" + id;
- String portletElementToDnD = "//div[@id='" + categoryTitle +
"/" + portletName + "']";
-
addNewPageUpToFinish(categoryTitle, portletName, pageName, portletElementToDnD);
// Wait for the other thread ...
sync.countDown();
sync.await();
+
+ // Uncomment this to make the test pass
+ // TODO: even though everything looks ok, it's not - navigation only contains
TestPage2 node when it should also contain TestPage1 node.
+ //if (id.equals("2"))
+ // Thread.sleep(5000);
+
// Now click Finish (both threads at the same time)
finishPageEdit();
- waitForTextPresent(portletName);
+
+ String failedText = "This node does not have any pages.";
+ String textPresent = waitForTextPresent(portletName, failedText);
+
+ Assert.assertNotSame(textPresent, failedText, "Concurrent Add Page issue
reproduced!");
+ Assert.assertEquals(textPresent, portletName, "");
+
+ finished();
}
+ /**
+ * Perform cleanup
+ * @throws IOException
+ */
+ private void test2() throws IOException
+ {
+ openPortal(true);
+
+ signInAsRoot();
+
+ cleanup();
+ }
+
+ /**
+ * TODO: Cleanup code doesn't yet work
+ *
+ * @throws IOException
+ */
+ private void cleanup() throws IOException
+ {
+ try
+ {
+ leavePageEdit();
+ }
+ catch (Exception ex)
+ {
+ log.warn("IGNORED: ", ex);
+ }
+
+ try
+ {
+ goToPageManagement();
+
+ try
+ {
+ searchAndDeletePage("TestPage1");
+ }
+ catch (Throwable ex)
+ {
+ log.warn("IGNORED: Failed to delete TestPage1: ", ex);
+ }
+
+ try
+ {
+ searchAndDeletePage("TestPage2");
+ }
+ catch (Throwable ex)
+ {
+ log.warn("IGNORED: Failed to delete TestPage2: ", ex);
+ }
+
+ }
+ catch (Throwable e)
+ {
+ log.warn("IGNORED: Failed to open PageManagement: ", e);
+ }
+
+ try
+ {
+ goToSiteManagement();
+
+ try
+ {
+ editNavigation("classic");
+ deleteNode("TestPage");
+ }
+ catch (Throwable ex)
+ {
+ log.warn("IGNORED: Failed to delete TestPage1: ", ex);
+ }
+
+ try
+ {
+ editNavigation("classic");
+ deleteNode("TestPage2");
+ }
+ catch (Throwable ex)
+ {
+ log.warn("IGNORED: Failed to delete TestPage2: ", ex);
+ }
+ }
+ catch (Throwable e)
+ {
+ log.warn("IGNORED: Failed to remove TestPage from navigation: ", e);
+ }
+ }
}
\ No newline at end of file