You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/09/29 18:34:36 UTC
svn commit: r1177356 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/corelib/pages/
main/java/org/apache/tapestry5/internal/pageload/
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/inte...
Author: hlship
Date: Thu Sep 29 16:34:36 2011
New Revision: 1177356
URL: http://svn.apache.org/viewvc?rev=1177356&view=rev
Log:
TAP5-1678: Implement core/PageCatalog page
Add support for tracking page construction time and number of components
Track number of times a Page has been activated
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app3/
tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app3/PageCatalogTests.groovy
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSource.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java?rev=1177356&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java Thu Sep 29 16:34:36 2011
@@ -0,0 +1,94 @@
+// Copyright 2011 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry5.corelib.pages;
+
+import org.apache.tapestry5.SymbolConstants;
+import org.apache.tapestry5.alerts.AlertManager;
+import org.apache.tapestry5.annotations.ContentType;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.internal.services.PageSource;
+import org.apache.tapestry5.internal.structure.Page;
+import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.ioc.annotations.Symbol;
+import org.apache.tapestry5.services.ComponentClassResolver;
+import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
+
+import java.util.Collection;
+
+/**
+ * Lists out the currently loaded pages, using a {@link Grid}. Provides an option to force all pages to be loaded. In development mode,
+ * includes an option to clear the page cache.
+ */
+@ContentType("text/html")
+public class PageCatalog
+{
+ @Property
+ @Inject
+ @Symbol(SymbolConstants.PRODUCTION_MODE)
+ private boolean productionMode;
+
+ @Inject
+ private PageSource pageSource;
+
+ @Inject
+ private ComponentResourceSelector selector;
+
+ @Inject
+ private ComponentClassResolver resolver;
+
+ @Inject
+ private AlertManager alertManager;
+
+ @Property
+ private Page page;
+
+ public Collection<Page> getPages()
+ {
+ return pageSource.getAllPages();
+ }
+
+ void onActionFromForceLoad()
+ {
+
+ int startCount = getPages().size();
+
+ for (String name : resolver.getPageNames())
+ {
+ pageSource.getPage(name);
+ }
+
+ int added = getPages().size() - startCount;
+
+ alertManager.info(String.format("Loaded %,d new pages for selector '%s'.", added, selector.toShortString()));
+ }
+
+ void onActionFromClearCache()
+ {
+ if (productionMode)
+ {
+ alertManager.error("Clearing the cache is not allowed in production mode");
+ return;
+ }
+
+ pageSource.clearCache();
+
+ alertManager.info("Page cache cleared.");
+ }
+
+ public String formatElapsed(long millis)
+ {
+ return String.format("%,d ms", millis);
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java?rev=1177356&r1=1177355&r2=1177356&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/ComponentAssemblerImpl.java Thu Sep 29 16:34:36 2011
@@ -14,17 +14,10 @@
package org.apache.tapestry5.internal.pageload;
-import java.util.List;
-import java.util.Map;
-
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.internal.services.ComponentInstantiatorSource;
import org.apache.tapestry5.internal.services.Instantiator;
-import org.apache.tapestry5.internal.structure.BodyPageElement;
-import org.apache.tapestry5.internal.structure.ComponentPageElement;
-import org.apache.tapestry5.internal.structure.ComponentPageElementImpl;
-import org.apache.tapestry5.internal.structure.ComponentPageElementResources;
-import org.apache.tapestry5.internal.structure.Page;
+import org.apache.tapestry5.internal.structure.*;
import org.apache.tapestry5.ioc.Invokable;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.OperationTracker;
@@ -41,6 +34,9 @@ import org.apache.tapestry5.services.Com
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
+import java.util.List;
+import java.util.Map;
+
class ComponentAssemblerImpl implements ComponentAssembler
{
private final ComponentAssemblerSource assemblerSource;
@@ -68,9 +64,9 @@ class ComponentAssemblerImpl implements
private Map<String, EmbeddedComponentAssembler> embeddedIdToAssembler;
public ComponentAssemblerImpl(ComponentAssemblerSource assemblerSource,
- ComponentInstantiatorSource instantiatorSource, ComponentClassResolver componentClassResolver,
- Instantiator instantiator, ComponentPageElementResources resources, OperationTracker tracker,
- Request request, SymbolSource symbolSource)
+ ComponentInstantiatorSource instantiatorSource, ComponentClassResolver componentClassResolver,
+ Instantiator instantiator, ComponentPageElementResources resources, OperationTracker tracker,
+ Request request, SymbolSource symbolSource)
{
this.assemblerSource = assemblerSource;
this.instantiatorSource = instantiatorSource;
@@ -98,8 +94,12 @@ class ComponentAssemblerImpl implements
{
PageAssembly pageAssembly = new PageAssembly(page);
+ long startTime = System.currentTimeMillis();
+
try
{
+ pageAssembly.componentCount++;
+
ComponentPageElement newElement = new ComponentPageElementImpl(pageAssembly.page, instantiator, resources,
request, symbolSource);
@@ -126,9 +126,10 @@ class ComponentAssemblerImpl implements
action.execute(pageAssembly);
}
+ page.setStats(System.currentTimeMillis() - startTime, pageAssembly.componentCount);
+
return pageAssembly.createdElement.peek();
- }
- catch (RuntimeException ex)
+ } catch (RuntimeException ex)
{
throw new RuntimeException(PageloadMessages.exceptionAssemblingRootComponent(pageAssembly.page.getName(),
InternalUtils.toMessage(ex)), ex);
@@ -147,8 +148,8 @@ class ComponentAssemblerImpl implements
}
public void assembleEmbeddedComponent(final PageAssembly pageAssembly,
- final EmbeddedComponentAssembler embeddedAssembler, final String embeddedId, final String elementName,
- final Location location)
+ final EmbeddedComponentAssembler embeddedAssembler, final String embeddedId, final String elementName,
+ final Location location)
{
ComponentName containerName = pageAssembly.componentName.peek();
@@ -172,6 +173,8 @@ class ComponentAssemblerImpl implements
ComponentPageElement newElement = container.newChild(embeddedId, embeddedName.nestedId,
embeddedName.completeId, elementName, instantiator, location);
+ pageAssembly.componentCount++;
+
pushNewElement(pageAssembly, newElement);
embeddedAssembler.addMixinsToElement(newElement);
@@ -181,8 +184,7 @@ class ComponentAssemblerImpl implements
popNewElement(pageAssembly);
pageAssembly.componentName.pop();
- }
- catch (RuntimeException ex)
+ } catch (RuntimeException ex)
{
throw new TapestryException(PageloadMessages.exceptionAssemblingEmbeddedComponent(embeddedId,
componentClassName, container.getCompleteId(), InternalUtils.toMessage(ex)), location, ex);
@@ -274,13 +276,16 @@ class ComponentAssemblerImpl implements
}
public EmbeddedComponentAssembler createEmbeddedAssembler(String embeddedId, String componentClassName,
- EmbeddedComponentModel embeddedModel, String mixins, Location location)
+ EmbeddedComponentModel embeddedModel, String mixins, Location location)
{
try
{
- if (InternalUtils.isBlank(componentClassName)) { throw new TapestryException(
- PageloadMessages.missingComponentType(), location, null); }
+ if (InternalUtils.isBlank(componentClassName))
+ {
+ throw new TapestryException(
+ PageloadMessages.missingComponentType(), location, null);
+ }
EmbeddedComponentAssemblerImpl embedded = new EmbeddedComponentAssemblerImpl(assemblerSource,
instantiatorSource, componentClassResolver, componentClassName, getSelector(), embeddedModel,
mixins, location);
@@ -299,9 +304,12 @@ class ComponentAssemblerImpl implements
String existingEmbeddedId = publishedParameterToEmbeddedId.get(publishedParameterName);
- if (existingEmbeddedId != null) { throw new TapestryException(
- PageloadMessages.parameterAlreadyPublished(publishedParameterName, embeddedId, instantiator
- .getModel().getComponentClassName(), existingEmbeddedId), location, null); }
+ if (existingEmbeddedId != null)
+ {
+ throw new TapestryException(
+ PageloadMessages.parameterAlreadyPublished(publishedParameterName, embeddedId, instantiator
+ .getModel().getComponentClassName(), existingEmbeddedId), location, null);
+ }
publishedParameterToEmbeddedId.put(publishedParameterName, embeddedId);
}
@@ -309,8 +317,7 @@ class ComponentAssemblerImpl implements
}
return embedded;
- }
- catch (Exception ex)
+ } catch (Exception ex)
{
throw new TapestryException(PageloadMessages.failureCreatingEmbeddedComponent(embeddedId, instantiator
.getModel().getComponentClassName(), InternalUtils.toMessage(ex)), location, ex);
@@ -333,20 +340,23 @@ class ComponentAssemblerImpl implements
// The complex case: a re-publish! Yes you can go deep here if you don't
// value your sanity!
- if (embeddedBinder != null) { return new ParameterBinder()
+ if (embeddedBinder != null)
{
- public void bind(ComponentPageElement element, Binding binding)
+ return new ParameterBinder()
{
- ComponentPageElement subelement = element.getEmbeddedElement(embeddedId);
+ public void bind(ComponentPageElement element, Binding binding)
+ {
+ ComponentPageElement subelement = element.getEmbeddedElement(embeddedId);
- embeddedBinder.bind(subelement, binding);
- }
+ embeddedBinder.bind(subelement, binding);
+ }
- public String getDefaultBindingPrefix(String metaDefault)
- {
- return embeddedBinder.getDefaultBindingPrefix(metaDefault);
- }
- }; }
+ public String getDefaultBindingPrefix(String metaDefault)
+ {
+ return embeddedBinder.getDefaultBindingPrefix(metaDefault);
+ }
+ };
+ }
final ParameterBinder innerBinder = embededdedComponentAssembler.createParameterBinder(parameterName);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java?rev=1177356&r1=1177355&r2=1177356&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/pageload/PageAssembly.java Thu Sep 29 16:34:36 2011
@@ -48,6 +48,11 @@ class PageAssembly
private final Set<String> flags = CollectionFactory.newSet();
+ /**
+ * Number of components constructed for this page instance.
+ */
+ int componentCount;
+
PageAssembly(Page page)
{
this.page = page;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSource.java?rev=1177356&r1=1177355&r2=1177356&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSource.java Thu Sep 29 16:34:36 2011
@@ -14,18 +14,18 @@
package org.apache.tapestry5.internal.services;
-import java.util.Locale;
-
import org.apache.tapestry5.internal.structure.Page;
import org.apache.tapestry5.ioc.Resource;
import org.apache.tapestry5.services.dynamic.DynamicTemplate;
import org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer;
import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
+import java.util.Set;
+
/**
* Access to localized page instances (which are now shared singletons, starting in release 5.2).
* This service is a wrapper around the {@link PageLoader} that caches the loaded pages.
- *
+ *
* @since 5.2.0
*/
public interface PageSource
@@ -34,7 +34,7 @@ public interface PageSource
* Clears the source's cache of loaded pages. This occurs when an outside change to the world invalidates
* created page instances. Introduced to handle the case where a page has a {@link DynamicTemplate}, but the
* underlying {@link Resource} is noticed to have changed.
- *
+ *
* @since 5.3
*/
void clearCache();
@@ -42,9 +42,19 @@ public interface PageSource
/**
* Returns a loaded instance of the indicated page, using the Locale and other information
* from the {@link ComponentResourceSelector} obtained from the {@link ComponentRequestSelectorAnalyzer}.
- *
+ *
* @param canonicalPageName
* @return existing, or newly created, page instance
*/
Page getPage(String canonicalPageName);
+
+ /**
+ * Returns all currently loaded pages. This will include any previously loaded pages not yet reclaimed by the
+ * garbage collector, and may include the same page loaded for different {@link ComponentResourceSelector}s. This is needed
+ * for reporting purposes only.
+ *
+ * @see org.apache.tapestry5.corelib.pages.PageCatalog
+ * @since 5.3
+ */
+ Set<Page> getAllPages();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java?rev=1177356&r1=1177355&r2=1177356&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java Thu Sep 29 16:34:36 2011
@@ -14,6 +14,8 @@
package org.apache.tapestry5.internal.services;
+import org.apache.tapestry5.func.F;
+import org.apache.tapestry5.func.Mapper;
import org.apache.tapestry5.internal.structure.Page;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.services.InvalidationListener;
@@ -22,6 +24,7 @@ import org.apache.tapestry5.services.pag
import java.lang.ref.SoftReference;
import java.util.Map;
+import java.util.Set;
public class PageSourceImpl implements PageSource, InvalidationListener
{
@@ -110,4 +113,15 @@ public class PageSourceImpl implements P
{
pageCache.clear();
}
+
+ public Set<Page> getAllPages()
+ {
+ return F.flow(pageCache.values()).map(new Mapper<SoftReference<Page>, Page>()
+ {
+ public Page map(SoftReference<Page> element)
+ {
+ return element.get();
+ }
+ }).removeNulls().toSet();
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java?rev=1177356&r1=1177355&r2=1177356&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java Thu Sep 29 16:34:36 2011
@@ -182,4 +182,37 @@ public interface Page
* Invoked to notify {@link PageResetListener} listeners.
*/
void pageReset();
+
+
+ /**
+ * Invoked once at the end of page construction, to provide page construction statistics.
+ *
+ * @since 5.3
+ */
+ void setStats(long assemblyTime, int componentCount);
+
+ /**
+ * Returns the time, in milliseconds, to construct the page.
+ *
+ * @since 5.3
+ */
+ long getAssemblyTime();
+
+ /**
+ * Returns the number of components on the page, including the root component. This is a rough
+ * measure of complexity.
+ *
+ * @since 5.3
+ */
+ int getComponentCount();
+
+ /**
+ * Returns the number of times the page has been attached to a request. This is a rough measure
+ * of how important the page is, relative to other pages. This value is volatile, changing constantly.
+ *
+ * @since 5.3
+ */
+ int getAttachCount();
+
+
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java?rev=1177356&r1=1177355&r2=1177356&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java Thu Sep 29 16:34:36 2011
@@ -28,6 +28,7 @@ import org.slf4j.Logger;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
public class PageImpl implements Page
@@ -50,6 +51,15 @@ public class PageImpl implements Page
private final Map<String, ComponentPageElement> idToComponent = CollectionFactory.newCaseInsensitiveMap();
+ // TODO: loadComplete, assemblyTime, and componentCount are each set once without thread semantics,
+ // but before the instance is published to other threads ... is that enough?
+
+ private long assemblyTime;
+
+ private int componentCount;
+
+ private final AtomicInteger attachCount = new AtomicInteger();
+
/**
* Obtained from the {@link org.apache.tapestry5.internal.services.PersistentFieldManager} when
* first needed,
@@ -75,6 +85,12 @@ public class PageImpl implements Page
fieldBundle = perThreadManager.createValue();
}
+ public void setStats(long assemblyTime, int componentCount)
+ {
+ this.assemblyTime = assemblyTime;
+ this.componentCount = componentCount;
+ }
+
@Override
public String toString()
{
@@ -174,6 +190,8 @@ public class PageImpl implements Page
public void attached()
{
+ attachCount.incrementAndGet();
+
for (PageLifecycleListener listener : lifecycleListeners)
listener.restoreStateBeforePageAttach();
@@ -233,4 +251,18 @@ public class PageImpl implements Page
return !resetListeners.isEmpty();
}
+ public long getAssemblyTime()
+ {
+ return assemblyTime;
+ }
+
+ public int getComponentCount()
+ {
+ return componentCount;
+ }
+
+ public int getAttachCount()
+ {
+ return attachCount.get();
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml?rev=1177356&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml Thu Sep 29 16:34:36 2011
@@ -0,0 +1,44 @@
+<html xml:space="default" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
+<head>
+ <title>Tapestry Page Catalog</title>
+</head>
+<body>
+
+<h1>Tapestry Page Catalog</h1>
+
+<t:alerts/>
+
+<p>
+ This page provides a list of pages currently loaded in the application.
+</p>
+
+<p>Actions:</p>
+<ul>
+ <li>
+ <t:pagelink page="pagecatalog">refresh the page</t:pagelink>
+ </li>
+ <li>
+ <t:actionlink t:id="forceLoad">load all pages</t:actionlink>
+ </li>
+ <t:if test="! productionMode">
+ <li>
+ <t:actionlink t:id="clearCache">clear the cache</t:actionlink>
+ </li>
+ </t:if>
+</ul>
+
+<t:grid source="pages" row="page" add="selector" reorder="name,selector">
+ <p:nameCell>
+ <t:pagelink page="prop:page.name">${page.name}</t:pagelink>
+ </p:nameCell>
+ <p:assemblyTimeCell>
+ ${formatElapsed(page.assemblyTime)}
+ </p:assemblyTimeCell>
+ <p:selectorCell>
+ ${page.selector.toShortString()}
+ </p:selectorCell>
+</t:grid>
+
+</body>
+
+</html>
\ No newline at end of file
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app3/PageCatalogTests.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app3/PageCatalogTests.groovy?rev=1177356&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app3/PageCatalogTests.groovy (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app3/PageCatalogTests.groovy Thu Sep 29 16:34:36 2011
@@ -0,0 +1,27 @@
+package org.apache.tapestry5.integration.app3
+
+import org.apache.tapestry5.test.SeleniumTestCase
+import org.testng.annotations.Test
+
+class PageCatalogTests extends SeleniumTestCase
+{
+
+ @Test
+ void load_page_catalog_page()
+ {
+
+ open("${baseURL}pagecatalog")
+
+ assertTitle "Tapestry Page Catalog"
+
+ clickAndWait "link=load all pages"
+
+ assertTitle "Tapestry Page Catalog"
+
+ clickAndWait "link=clear the cache"
+
+ assertTitle "Tapestry Page Catalog"
+
+ assertTextPresent "Page cache cleared"
+ }
+}