Browse Source

Merge remote-tracking branch 'origin/6.8' into master

tags/7.0.0.alpha1
Leif Åstrand 12 years ago
parent
commit
2eff8c02ab
53 changed files with 2778 additions and 251 deletions
  1. 0
    0
      WebContent/VAADIN/themes/base/common/img/ajax-loader.gif
  2. 0
    0
      WebContent/VAADIN/themes/base/common/img/loading-indicator-delay.gif
  3. 0
    0
      WebContent/VAADIN/themes/base/common/img/loading-indicator-wait.gif
  4. 4
    0
      WebContent/VAADIN/themes/reindeer-tests/styles.css
  5. 0
    0
      WebContent/VAADIN/themes/runo/accordion/img/collapsed-icon.png
  6. 0
    0
      WebContent/VAADIN/themes/runo/accordion/img/expanded-icon.png
  7. 0
    0
      WebContent/VAADIN/themes/runo/accordion/img/selected-bg.png
  8. 0
    0
      WebContent/VAADIN/themes/runo/icons/16/error.png
  9. 0
    0
      WebContent/VAADIN/themes/runo/slider/img/handle-horizontal.png
  10. 0
    0
      WebContent/VAADIN/themes/runo/slider/img/handle-vertical.png
  11. 0
    0
      WebContent/VAADIN/themes/tests-tickets/icons/au.gif
  12. 0
    0
      WebContent/VAADIN/themes/tests-tickets/icons/fi.gif
  13. 0
    0
      WebContent/VAADIN/themes/tests-tickets/icons/hu.gif
  14. 0
    0
      WebContent/VAADIN/themes/tests-tickets/icons/se.gif
  15. 0
    0
      build/bin/closed-to-rn.py
  16. 0
    0
      build/bin/mergetool.py
  17. 0
    0
      build/bin/package-diff.py
  18. 0
    0
      build/bin/svnlog-to-rn.py
  19. 0
    0
      build/bin/tagrelease.py
  20. 2
    1
      build/build.xml
  21. 0
    0
      build/cssoptimizer/cssoptimizer
  22. 16
    1
      src/com/vaadin/data/util/ContainerOrderedWrapper.java
  23. 5
    0
      src/com/vaadin/data/util/FilesystemContainer.java
  24. 41
    9
      src/com/vaadin/terminal/Scrollable.java
  25. 0
    0
      src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
  26. 0
    0
      src/com/vaadin/terminal/gwt/client/VDebugConsole.java
  27. 85
    7
      src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
  28. 1
    1
      src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java
  29. 35
    5
      src/com/vaadin/ui/Panel.java
  30. 313
    102
      src/com/vaadin/ui/Table.java
  31. 21
    1
      src/com/vaadin/ui/TreeTable.java
  32. 3
    1
      tests/integration_base_files/base.xml
  33. 11
    3
      tests/integration_tests.xml
  34. 16
    0
      tests/server-side/com/vaadin/data/util/FileSystemContainerTest.java
  35. 1
    1
      tests/test.xml
  36. 0
    6
      tests/testbench/com/vaadin/tests/application/WebBrowserTest.html
  37. 0
    0
      tests/testbench/com/vaadin/tests/components/combobox/fi.gif
  38. 0
    0
      tests/testbench/com/vaadin/tests/components/combobox/se.gif
  39. 0
    0
      tests/testbench/com/vaadin/tests/components/menubar/MenuBarRunsOutOfBrowser.html
  40. 0
    0
      tests/testbench/com/vaadin/tests/components/table/fi.gif
  41. 0
    0
      tests/testbench/com/vaadin/tests/components/table/se.gif
  42. 92
    0
      tests/testbench/com/vaadin/tests/components/treetable/DynamicallyModified.html
  43. 125
    113
      tests/testbench/com/vaadin/tests/components/treetable/DynamicallyModified.java
  44. 528
    0
      tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html
  45. 238
    0
      tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java
  46. 55
    0
      tests/testbench/com/vaadin/tests/components/treetable/TreeTableNegativeArraySize.html
  47. 56
    0
      tests/testbench/com/vaadin/tests/components/treetable/TreeTablePartialUpdatesPageLength0.html
  48. 68
    0
      tests/testbench/com/vaadin/tests/components/treetable/TreeTablePartialUpdatesPageLength0.java
  49. 58
    0
      tests/testbench/com/vaadin/tests/components/upload/TestFileUpload.java
  50. BIN
      tests/testbench/com/vaadin/tests/components/upload/file-binary-cb4a65687deb859957ad4b0fd9d67eac.png
  51. 1004
    0
      tests/testbench/com/vaadin/tests/components/upload/file-text-6ebed606225d0b6254d45f51aa2dfe9f
  52. 0
    0
      tests/testbench/com/vaadin/tests/integration/fi.gif
  53. 0
    0
      tests/testbench/com/vaadin/tests/integration/se.gif

+ 0
- 0
WebContent/VAADIN/themes/base/common/img/ajax-loader.gif View File


+ 0
- 0
WebContent/VAADIN/themes/base/common/img/loading-indicator-delay.gif View File


+ 0
- 0
WebContent/VAADIN/themes/base/common/img/loading-indicator-wait.gif View File


+ 4
- 0
WebContent/VAADIN/themes/reindeer-tests/styles.css View File

@@ -0,0 +1,4 @@
@import url(../reindeer/styles.css);

.table-equal-rowheight .v-table-row {height: 30px;}
.table-equal-rowheight .v-table-row-odd {height: 30px;}

+ 0
- 0
WebContent/VAADIN/themes/runo/accordion/img/collapsed-icon.png View File


+ 0
- 0
WebContent/VAADIN/themes/runo/accordion/img/expanded-icon.png View File


+ 0
- 0
WebContent/VAADIN/themes/runo/accordion/img/selected-bg.png View File


+ 0
- 0
WebContent/VAADIN/themes/runo/icons/16/error.png View File


+ 0
- 0
WebContent/VAADIN/themes/runo/slider/img/handle-horizontal.png View File


+ 0
- 0
WebContent/VAADIN/themes/runo/slider/img/handle-vertical.png View File


+ 0
- 0
WebContent/VAADIN/themes/tests-tickets/icons/au.gif View File


+ 0
- 0
WebContent/VAADIN/themes/tests-tickets/icons/fi.gif View File


+ 0
- 0
WebContent/VAADIN/themes/tests-tickets/icons/hu.gif View File


+ 0
- 0
WebContent/VAADIN/themes/tests-tickets/icons/se.gif View File


+ 0
- 0
build/bin/closed-to-rn.py View File


+ 0
- 0
build/bin/mergetool.py View File


+ 0
- 0
build/bin/package-diff.py View File


+ 0
- 0
build/bin/svnlog-to-rn.py View File


+ 0
- 0
build/bin/tagrelease.py View File


+ 2
- 1
build/build.xml View File

@@ -948,7 +948,8 @@
>
<filter includes="com.vaadin.*" />
<filter excludes="com.vaadin.tests.*" />
<filter excludes="com.vaadin.terminal.gwt.*" />
<filter excludes="com.vaadin.terminal.gwt.client.*" />
<filter excludes="com.vaadin.terminal.gwt.widgetsetutils.*" />
<filter excludes="*Test*" />
<filter excludes="com.vaadin.launcher.*" />
</instr>

+ 0
- 0
build/cssoptimizer/cssoptimizer View File


+ 16
- 1
src/com/vaadin/data/util/ContainerOrderedWrapper.java View File

@@ -67,6 +67,13 @@ public class ContainerOrderedWrapper implements Container.Ordered,
*/
private boolean ordered = false;

/**
* The last known size of the wrapped container. Used to check whether items
* have been added or removed to the wrapped container, when the wrapped
* container does not send ItemSetChangeEvents.
*/
private int lastKnownSize = -1;

/**
* Constructs a new ordered wrapper for an existing Container. Works even if
* the to-be-wrapped container already implements the Container.Ordered
@@ -457,7 +464,15 @@ public class ContainerOrderedWrapper implements Container.Ordered,
* here, we use the default documentation from implemented interface.
*/
public int size() {
return container.size();
int newSize = container.size();
if (lastKnownSize != -1 && newSize != lastKnownSize
&& !(container instanceof Container.ItemSetChangeNotifier)) {
// Update the internal cache when the size of the container changes
// and the container is incapable of sending ItemSetChangeEvents
updateOrderWrapper();
}
lastKnownSize = newSize;
return newSize;
}

/*

+ 5
- 0
src/com/vaadin/data/util/FilesystemContainer.java View File

@@ -395,6 +395,11 @@ public class FilesystemContainer implements Container.Hierarchical {
} else {
l = f.listFiles();
}
if (l == null) {
// File.listFiles returns null if File does not exist or if there
// was an IO error (permission denied)
return;
}
final List<File> ll = Arrays.asList(l);
Collections.sort(ll);


+ 41
- 9
src/com/vaadin/terminal/Scrollable.java View File

@@ -8,8 +8,9 @@ import java.io.Serializable;

/**
* <p>
* This interface is implemented by all visual objects that can be scrolled. The
* unit of scrolling is pixel.
* This interface is implemented by all visual objects that can be scrolled
* programmatically from the server-side, or for which it is possible to know
* the scroll position on the server-side. The unit of scrolling is pixel.
* </p>
*
* @author IT Mill Ltd.
@@ -39,6 +40,13 @@ public interface Scrollable extends Serializable {
* scrolled right.
* </p>
*
* <p>
* The method only has effect if programmatic scrolling is enabled for the
* scrollable. Some implementations may require enabling programmatic before
* this method can be used. See {@link #setScrollable(boolean)} for more
* information.
* </p>
*
* @param pixelsScrolled
* the xOffset.
*/
@@ -64,30 +72,54 @@ public interface Scrollable extends Serializable {
* scrolled down.
* </p>
*
* <p>
* The method only has effect if programmatic scrolling is enabled for the
* scrollable. Some implementations may require enabling programmatic before
* this method can be used. See {@link #setScrollable(boolean)} for more
* information.
* </p>
*
* <p>
* The scrolling position is limited by the current height of the content
* area. If the position is below the height, it is scrolled to the bottom.
* However, if the same response also adds height to the content area,
* scrolling to bottom only scrolls to the bottom of the previous content
* area.
* </p>
*
* @param pixelsScrolled
* the yOffset.
*/
public void setScrollTop(int pixelsScrolled);

/**
* Is the scrolling enabled.
* Is programmatic scrolling enabled.
*
* <p>
* Enabling scrolling allows the user to scroll the scrollable view
* interactively
* Whether programmatic scrolling with {@link #setScrollLeft(int)} and
* {@link #setScrollTop(int)} is enabled.
* </p>
*
* @return <code>true</code> if the scrolling is allowed, otherwise
* @return <code>true</code> if the scrolling is enabled, otherwise
* <code>false</code>.
*/
public boolean isScrollable();

/**
* Enables or disables scrolling..
* Enables or disables programmatic scrolling.
*
* <p>
* Enables setting the scroll position with {@link #setScrollLeft(int)} and
* {@link #setScrollTop(int)}. Implementations of the interface may have
* programmatic scrolling disabled by default, in which case you need to
* enable it to use the mentioned methods.
* </p>
*
* <p>
* Enabling scrolling allows the user to scroll the scrollable view
* interactively
* Notice that this does <i>not</i> control whether scroll bars are shown
* for a scrollable component. That normally happens automatically when the
* content grows too big for the component, relying on the "overflow: auto"
* property in CSS.
* </p>
*
* @param isScrollingEnabled

+ 0
- 0
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java View File


+ 0
- 0
src/com/vaadin/terminal/gwt/client/VDebugConsole.java View File


+ 85
- 7
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java View File

@@ -104,6 +104,9 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
VHasDropHandler, FocusHandler, BlurHandler, Focusable, ActionOwner {

public static final String ATTRIBUTE_PAGEBUFFER_FIRST = "pb-ft";
public static final String ATTRIBUTE_PAGEBUFFER_LAST = "pb-l";

private static final String ROW_HEADER_COLUMN_KEY = "0";

public static final String CLASSNAME = "v-table";
@@ -203,6 +206,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,

private String[] bodyActionKeys;

private boolean enableDebug = false;

/**
* Represents a select range of rows
*/
@@ -423,6 +428,21 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,

private int lastRenderedHeight;

/**
* Values (serverCacheFirst+serverCacheLast) sent by server that tells which
* rows (indexes) are in the server side cache (page buffer). -1 means
* unknown. The server side cache row MUST MATCH the client side cache rows.
*
* If the client side cache contains additional rows with e.g. buttons, it
* will cause out of sync when such a button is pressed.
*
* If the server side cache contains additional rows with e.g. buttons,
* scrolling in the client will cause empty buttons to be rendered
* (cached=true request for non-existing components)
*/
private int serverCacheFirst = -1;
private int serverCacheLast = -1;

public VScrollTable() {
setMultiSelectMode(MULTISELECT_MODE_DEFAULT);

@@ -798,6 +818,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
rendering = true;

if (uidl.hasAttribute(ATTRIBUTE_PAGEBUFFER_FIRST)) {
serverCacheFirst = uidl.getIntAttribute(ATTRIBUTE_PAGEBUFFER_FIRST);
serverCacheLast = uidl.getIntAttribute(ATTRIBUTE_PAGEBUFFER_LAST);
} else {
serverCacheFirst = -1;
serverCacheLast = -1;
}
/*
* We need to do this before updateComponent since updateComponent calls
* this.setHeight() which will calculate a new body height depending on
@@ -1404,8 +1431,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
int count = partialRowUpdates.getIntAttribute("numurows");
scrollBody.unlinkRows(firstRowIx, count);
scrollBody.insertRows(partialRowUpdates, firstRowIx, count);

discardRowsOutsideCacheWindow();
}

/**
@@ -1413,24 +1438,71 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* caching window.
*/
protected void discardRowsOutsideCacheWindow() {
final int optimalFirstRow = (int) (firstRowInViewPort - pageLength
int firstRowToKeep = (int) (firstRowInViewPort - pageLength
* cache_rate);
int lastRowToKeep = (int) (firstRowInViewPort + pageLength + pageLength
* cache_rate);
debug("Client side calculated cache rows to keep: " + firstRowToKeep
+ "-" + lastRowToKeep);

if (serverCacheFirst != -1) {
firstRowToKeep = serverCacheFirst;
lastRowToKeep = serverCacheLast;
debug("Server cache rows that override: " + serverCacheFirst + "-"
+ serverCacheLast);
if (firstRowToKeep < scrollBody.getFirstRendered()
|| lastRowToKeep > scrollBody.getLastRendered()) {
debug("*** Server wants us to keep " + serverCacheFirst + "-"
+ serverCacheLast + " but we only have rows "
+ scrollBody.getFirstRendered() + "-"
+ scrollBody.getLastRendered() + " rendered!");
}
}
discardRowsOutsideOf(firstRowToKeep, lastRowToKeep);

scrollBody.fixSpacers();

scrollBody.restoreRowVisibility();
}

private void discardRowsOutsideOf(int optimalFirstRow, int optimalLastRow) {
/*
* firstDiscarded and lastDiscarded are only calculated for debug
* purposes
*/
int firstDiscarded = -1, lastDiscarded = -1;
boolean cont = true;
while (cont && scrollBody.getLastRendered() > optimalFirstRow
&& scrollBody.getFirstRendered() < optimalFirstRow) {
if (firstDiscarded == -1) {
firstDiscarded = scrollBody.getFirstRendered();
}

// removing row from start
cont = scrollBody.unlinkRow(true);
}
final int optimalLastRow = (int) (firstRowInViewPort + pageLength + pageLength
* cache_rate);
if (firstDiscarded != -1) {
lastDiscarded = scrollBody.getFirstRendered() - 1;
debug("Discarded rows " + firstDiscarded + "-" + lastDiscarded);
}
firstDiscarded = lastDiscarded = -1;

cont = true;
while (cont && scrollBody.getLastRendered() > optimalLastRow) {
if (lastDiscarded == -1) {
lastDiscarded = scrollBody.getLastRendered();
}

// removing row from the end
cont = scrollBody.unlinkRow(false);
}
scrollBody.fixSpacers();
if (lastDiscarded != -1) {
firstDiscarded = scrollBody.getLastRendered() + 1;
debug("Discarded rows " + firstDiscarded + "-" + lastDiscarded);
}

scrollBody.restoreRowVisibility();
debug("Now in cache: " + scrollBody.getFirstRendered() + "-"
+ scrollBody.getLastRendered());
}

/**
@@ -6752,4 +6824,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
lazyAdjustColumnWidths.schedule(LAZY_COLUMN_ADJUST_TIMEOUT);
}
}

private void debug(String msg) {
if (enableDebug) {
VConsole.error(msg);
}
}
}

+ 1
- 1
src/com/vaadin/terminal/gwt/widgetsetutils/WidgetSetBuilder.java View File

@@ -66,7 +66,7 @@ public class WidgetSetBuilder {
if (!parent.mkdirs()) {
throw new IOException(
"Could not create directory for the widgetset: "
+ parent.getCanonicalPath());
+ parent.getPath());
}
}
widgetsetFile.createNewFile();

+ 35
- 5
src/com/vaadin/ui/Panel.java View File

@@ -405,8 +405,16 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
return scrollable;
}

/*
* (non-Javadoc)
/**
* Sets the panel as programmatically scrollable.
*
* <p>
* Panel is by default not scrollable programmatically with
* {@link #setScrollLeft(int)} and {@link #setScrollTop(int)}, so if you use
* those methods, you need to enable scrolling with this method. Components
* that extend Panel may have a different default for the programmatic
* scrollability.
* </p>
*
* @see com.vaadin.terminal.Scrollable#setScrollable(boolean)
*/
@@ -417,10 +425,19 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
}
}

/*
* (non-Javadoc)
/**
* Sets the horizontal scroll position.
*
* <p>
* Setting the horizontal scroll position with this method requires that
* programmatic scrolling of the component has been enabled. For Panel it is
* disabled by default, so you have to call {@link #setScrollable(boolean)}.
* Components extending Panel may have a different default for programmatic
* scrollability.
* </p>
*
* @see com.vaadin.terminal.Scrollable#setScrollLeft(int)
* @see #setScrollable(boolean)
*/
public void setScrollLeft(int pixelsScrolled) {
if (pixelsScrolled < 0) {
@@ -441,7 +458,20 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
setScrollLeft(pixels);
}

/* Documented in interface */
/**
* Sets the vertical scroll position.
*
* <p>
* Setting the vertical scroll position with this method requires that
* programmatic scrolling of the component has been enabled. For Panel it is
* disabled by default, so you have to call {@link #setScrollable(boolean)}.
* Components extending Panel may have a different default for programmatic
* scrollability.
* </p>
*
* @see com.vaadin.terminal.Scrollable#setScrollTop(int)
* @see #setScrollable(boolean)
*/
public void setScrollTop(int pixelsScrolledDown) {
if (pixelsScrolledDown < 0) {
throw new IllegalArgumentException(

+ 313
- 102
src/com/vaadin/ui/Table.java View File

@@ -522,8 +522,7 @@ public class Table extends AbstractSelect implements Action.Container,
this.visibleColumns = newVC;

// Assures visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

/**
@@ -721,8 +720,8 @@ public class Table extends AbstractSelect implements Action.Container,
}
this.columnAlignments = newCA;

// Assures the visual refresh
resetPageBuffer();
// Assures the visual refresh. No need to reset the page buffer before
// as the content has not changed, only the alignments.
refreshRenderedCells();
}

@@ -860,8 +859,7 @@ public class Table extends AbstractSelect implements Action.Container,
if (pageLength >= 0 && this.pageLength != pageLength) {
this.pageLength = pageLength;
// Assures the visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
}

@@ -982,8 +980,7 @@ public class Table extends AbstractSelect implements Action.Container,
}

// Assures the visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();

}

@@ -1107,7 +1104,8 @@ public class Table extends AbstractSelect implements Action.Container,
columnAlignments.put(propertyId, alignment);
}

// Assures the visual refresh
// Assures the visual refresh. No need to reset the page buffer before
// as the content has not changed, only the alignments.
refreshRenderedCells();
}

@@ -1147,8 +1145,7 @@ public class Table extends AbstractSelect implements Action.Container,
}

// Assures the visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

/**
@@ -1173,7 +1170,8 @@ public class Table extends AbstractSelect implements Action.Container,
collapsedColumns.clear();
}

// Assures the visual refresh
// Assures the visual refresh. No need to reset the page buffer before
// as the content has not changed, only the alignments.
refreshRenderedCells();
}

@@ -1227,8 +1225,7 @@ public class Table extends AbstractSelect implements Action.Container,
visibleColumns = newOrder;

// Assure visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

/**
@@ -1322,8 +1319,7 @@ public class Table extends AbstractSelect implements Action.Container,
}
if (needsPageBufferReset) {
// Assures the visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
}

@@ -1418,7 +1414,9 @@ public class Table extends AbstractSelect implements Action.Container,
}

/**
* Refreshes rendered rows
* Refreshes the rows in the internal cache. Only if
* {@link #resetPageBuffer()} is called before this then all values are
* guaranteed to be recreated.
*/
protected void refreshRenderedCells() {
if (getParent() == null) {
@@ -1474,39 +1472,93 @@ public class Table extends AbstractSelect implements Action.Container,
requestRepaint();
}

/**
* Requests that the Table should be repainted as soon as possible.
*
* Note that a {@code Table} does not necessarily repaint its contents when
* this method has been called. See {@link #refreshRowCache()} for forcing
* an update of the contents.
*/
@Override
public void requestRepaint() {
// Overridden only for javadoc
super.requestRepaint();
}

private void removeRowsFromCacheAndFillBottom(int firstIndex, int rows) {
int totalCachedRows = pageBuffer[CELL_ITEMID].length;
int totalRows = size();
int cacheIx = firstIndex - pageBufferFirstIndex;
int firstIndexInPageBuffer = firstIndex - pageBufferFirstIndex;

// Make sure that no components leak.
/*
* firstIndexInPageBuffer is the first row to be removed. "rows" rows
* after that should be removed. If the page buffer does not contain
* that many rows, we only remove the rows that actually are in the page
* buffer.
*/
if (firstIndexInPageBuffer + rows > totalCachedRows) {
rows = totalCachedRows - firstIndexInPageBuffer;
}

/*
* Unregister components that will no longer be in the page buffer to
* make sure that no components leak.
*/
unregisterComponentsAndPropertiesInRows(firstIndex, rows);

int newCachedRowCount = totalRows < totalCachedRows ? totalRows
: totalCachedRows;
int firstAppendedRow = newCachedRowCount > rows ? newCachedRowCount
- rows : firstIndex;
int rowsToAdd = Math.min(rows, totalCachedRows - firstAppendedRow);
rowsToAdd = Math.min(rowsToAdd, totalRows
- (firstAppendedRow + pageBufferFirstIndex));
if (rowsToAdd == 0) {
return;
/*
* The number of rows that should be in the cache after this operation
* is done (pageBuffer currently contains the expanded items).
*/
int newCachedRowCount = totalCachedRows;
if (newCachedRowCount + pageBufferFirstIndex > totalRows) {
newCachedRowCount = totalRows - pageBufferFirstIndex;
}

/*
* The index at which we should render the first row that does not come
* from the previous page buffer.
*/
int firstAppendedRowInPageBuffer = totalCachedRows - rows;
int firstAppendedRow = firstAppendedRowInPageBuffer
+ pageBufferFirstIndex;

/*
* Calculate the maximum number of new rows that we can add to the page
* buffer. Less than the rows we removed if the container does not
* contain that many items afterwards.
*/
int maxRowsToRender = (totalRows - firstAppendedRow);
int rowsToAdd = rows;
if (rowsToAdd > maxRowsToRender) {
rowsToAdd = maxRowsToRender;
}
Object[][] cells = getVisibleCellsNoCache(firstAppendedRow, rowsToAdd,
false);

// Create the new cache buffer by copying data from the old one and
// appending more rows if applicable.
Object[][] cells = null;
if (rowsToAdd > 0) {
cells = getVisibleCellsNoCache(firstAppendedRow, rowsToAdd, false);
}
/*
* Create the new cache buffer by copying the first rows from the old
* buffer, moving the following rows upwards and appending more rows if
* applicable.
*/
Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount];
for (int ix = 0; ix < newCachedRowCount; ix++) {
for (int i = 0; i < pageBuffer.length; i++) {
if (ix >= firstAppendedRow) {
newPageBuffer[i][ix] = cells[i][ix - firstAppendedRow];
} else if (ix >= cacheIx && ix + rows < totalCachedRows) {
newPageBuffer[i][ix] = pageBuffer[i][ix + rows];
} else {
newPageBuffer[i][ix] = pageBuffer[i][ix];
}

for (int i = 0; i < pageBuffer.length; i++) {
for (int row = 0; row < firstIndexInPageBuffer; row++) {
// Copy the first rows
newPageBuffer[i][row] = pageBuffer[i][row];
}
for (int row = firstIndexInPageBuffer; row < firstAppendedRowInPageBuffer; row++) {
// Move the rows that were after the expanded rows
newPageBuffer[i][row] = pageBuffer[i][row + rows];
}
for (int row = firstAppendedRowInPageBuffer; row < newCachedRowCount; row++) {
// Add the newly rendered rows. Only used if rowsToAdd > 0
// (cells != null)
newPageBuffer[i][row] = cells[i][row
- firstAppendedRowInPageBuffer];
}
}
pageBuffer = newPageBuffer;
@@ -1526,46 +1578,143 @@ public class Table extends AbstractSelect implements Action.Container,
return cells;
}

/**
* @param firstIndex
* The position where new rows should be inserted
* @param rows
* The maximum number of rows that should be inserted at position
* firstIndex. Less rows will be inserted if the page buffer is
* too small.
* @return
*/
private Object[][] getVisibleCellsInsertIntoCache(int firstIndex, int rows) {
Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false);
logger.finest("Insert " + rows + " rows at index " + firstIndex
+ " to existing page buffer requested");

// Page buffer must not become larger than pageLength*cacheRate before
// or after the current page
int minPageBufferIndex = getCurrentPageFirstItemIndex()
- (int) (getPageLength() * getCacheRate());
if (minPageBufferIndex < 0) {
minPageBufferIndex = 0;
}

int maxPageBufferIndex = getCurrentPageFirstItemIndex()
+ (int) (getPageLength() * (1 + getCacheRate()));
int maxBufferSize = maxPageBufferIndex - minPageBufferIndex;

if (getPageLength() == 0) {
// If pageLength == 0 then all rows should be rendered
maxBufferSize = pageBuffer[0].length + rows;
}
/*
* Number of rows that were previously cached. This is not necessarily
* the same as pageLength if we do not have enough rows in the
* container.
*/
int currentlyCachedRowCount = pageBuffer[CELL_ITEMID].length;
int lastCachedRow = currentlyCachedRowCount - rows;
int cacheIx = firstIndex - pageBufferFirstIndex;

// Unregister all components that fall beyond the cache limits after
// inserting the new rows.
unregisterComponentsAndPropertiesInRows(lastCachedRow + 1,
currentlyCachedRowCount - lastCachedRow);
/*
* firstIndexInPageBuffer is the offset in pageBuffer where the new rows
* will be inserted (firstIndex is the index in the whole table).
*
* E.g. scrolled down to row 1000: firstIndex==1010,
* pageBufferFirstIndex==1000 -> cacheIx==10
*/
int firstIndexInPageBuffer = firstIndex - pageBufferFirstIndex;

/* If rows > size available in page buffer */
if (firstIndexInPageBuffer + rows > maxBufferSize) {
rows = maxBufferSize - firstIndexInPageBuffer;
}

/*
* "rows" rows will be inserted at firstIndex. Find out how many old
* rows fall outside the new buffer so we can unregister components in
* the cache.
*/

/* All rows until the insertion point remain, always. */
int firstCacheRowToRemoveInPageBuffer = firstIndexInPageBuffer;

/*
* IF there is space remaining in the buffer after the rows have been
* inserted, we can keep more rows.
*/
int numberOfOldRowsAfterInsertedRows = maxBufferSize
- firstIndexInPageBuffer - rows;
if (numberOfOldRowsAfterInsertedRows > 0) {
firstCacheRowToRemoveInPageBuffer += numberOfOldRowsAfterInsertedRows;
}

if (firstCacheRowToRemoveInPageBuffer <= currentlyCachedRowCount) {
/*
* Unregister all components that fall beyond the cache limits after
* inserting the new rows.
*/
unregisterComponentsAndPropertiesInRows(
firstCacheRowToRemoveInPageBuffer + pageBufferFirstIndex,
currentlyCachedRowCount - firstCacheRowToRemoveInPageBuffer
+ pageBufferFirstIndex);
}

// Calculate the new cache size
int newCachedRowCount = currentlyCachedRowCount;
if (pageLength == 0 || currentlyCachedRowCount < pageLength) {
if (maxBufferSize == 0 || currentlyCachedRowCount < maxBufferSize) {
newCachedRowCount = currentlyCachedRowCount + rows;
if (pageLength > 0 && newCachedRowCount > pageLength) {
newCachedRowCount = pageLength;
if (maxBufferSize > 0 && newCachedRowCount > maxBufferSize) {
newCachedRowCount = maxBufferSize;
}
}

// Create the new cache buffer and fill it with the data from the old
// buffer as well as the inserted rows.
/* Paint the new rows into a separate buffer */
Object[][] cells = getVisibleCellsNoCache(firstIndex, rows, false);

/*
* Create the new cache buffer and fill it with the data from the old
* buffer as well as the inserted rows.
*/
Object[][] newPageBuffer = new Object[pageBuffer.length][newCachedRowCount];
for (int ix = 0; ix < newCachedRowCount; ix++) {
for (int i = 0; i < pageBuffer.length; i++) {
if (ix >= cacheIx && ix < cacheIx + rows) {
newPageBuffer[i][ix] = cells[i][ix - cacheIx];
} else if (ix >= cacheIx + rows) {
newPageBuffer[i][ix] = pageBuffer[i][ix - rows];
} else {
newPageBuffer[i][ix] = pageBuffer[i][ix];
}

for (int i = 0; i < pageBuffer.length; i++) {
for (int row = 0; row < firstIndexInPageBuffer; row++) {
// Copy the first rows
newPageBuffer[i][row] = pageBuffer[i][row];
}
for (int row = firstIndexInPageBuffer; row < firstIndexInPageBuffer
+ rows; row++) {
// Copy the newly created rows
newPageBuffer[i][row] = cells[i][row - firstIndexInPageBuffer];
}
for (int row = firstIndexInPageBuffer + rows; row < newCachedRowCount; row++) {
// Move the old rows down below the newly inserted rows
newPageBuffer[i][row] = pageBuffer[i][row - rows];
}
}
pageBuffer = newPageBuffer;
logger.finest("Page Buffer now contains "
+ pageBuffer[CELL_ITEMID].length + " rows ("
+ pageBufferFirstIndex + "-"
+ (pageBufferFirstIndex + pageBuffer[CELL_ITEMID].length - 1)
+ ")");
return cells;
}

/**
* Render rows with index "firstIndex" to "firstIndex+rows-1" to a new
* buffer.
*
* Reuses values from the current page buffer if the rows are found there.
*
* @param firstIndex
* @param rows
* @param replaceListeners
* @return
*/
private Object[][] getVisibleCellsNoCache(int firstIndex, int rows,
boolean replaceListeners) {
logger.finest("Render visible cells for rows " + firstIndex + "-"
+ (firstIndex + rows - 1));
final Object[] colids = getVisibleColumns();
final int cols = colids.length;

@@ -1747,6 +1896,8 @@ public class Table extends AbstractSelect implements Action.Container,
}

protected void registerComponent(Component component) {
logger.finest("Registered " + component.getClass().getSimpleName()
+ ": " + component.getCaption());
if (component.getParent() != this) {
component.setParent(this);
}
@@ -1772,9 +1923,13 @@ public class Table extends AbstractSelect implements Action.Container,

/**
* @param firstIx
* Index of the first row to process. Global index, not relative
* to page buffer.
* @param count
*/
private void unregisterComponentsAndPropertiesInRows(int firstIx, int count) {
logger.finest("Unregistering components in rows " + firstIx + "-"
+ (firstIx + count - 1));
Object[] colids = getVisibleColumns();
if (pageBuffer != null && pageBuffer[CELL_ITEMID].length > 0) {
int bufSize = pageBuffer[CELL_ITEMID].length;
@@ -1854,6 +2009,8 @@ public class Table extends AbstractSelect implements Action.Container,
* a set of components that should be unregistered.
*/
protected void unregisterComponent(Component component) {
logger.finest("Unregistered " + component.getClass().getSimpleName()
+ ": " + component.getCaption());
component.setParent(null);
/*
* Also remove property data sources to unregister listeners keeping the
@@ -1917,7 +2074,8 @@ public class Table extends AbstractSelect implements Action.Container,
setItemCaptionMode(mode);
}

// Assure visual refresh
// Assures the visual refresh. No need to reset the page buffer before
// as the content has not changed, only the alignments.
refreshRenderedCells();
}

@@ -1983,13 +2141,35 @@ public class Table extends AbstractSelect implements Action.Container,
}

if (!(items instanceof Container.ItemSetChangeNotifier)) {
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

return itemId;
}

/**
* Discards and recreates the internal row cache. Call this if you make
* changes that affect the rows but the information about the changes are
* not automatically propagated to the Table.
* <p>
* Do not call this e.g. if you have updated the data model through a
* Property. These types of changes are automatically propagated to the
* Table.
* <p>
* A typical case when this is needed is if you update a generator (e.g.
* CellStyleGenerator) and want to ensure that the rows are redrawn with new
* styles.
* <p>
* <i>Note that calling this method is not cheap so avoid calling it
* unnecessarily.</i>
*
* @since 6.7.2
*/
public void refreshRowCache() {
resetPageBuffer();
refreshRenderedCells();
}

@Override
public void setContainerDataSource(Container newDataSource) {

@@ -2220,6 +2400,8 @@ public class Table extends AbstractSelect implements Action.Container,
}
}
}
logger.finest("Client wants rows " + reqFirstRowToPaint + "-"
+ (reqFirstRowToPaint + reqRowsToPaint - 1));
clientNeedsContentRefresh = true;
}

@@ -2485,6 +2667,21 @@ public class Table extends AbstractSelect implements Action.Container,
// Rows
if (isPartialRowUpdate() && painted && !target.isFullRepaint()) {
paintPartialRowUpdate(target, actionSet);
/*
* Send the page buffer indexes to ensure that the client side stays
* in sync. Otherwise we _might_ have the situation where the client
* side discards too few or too many rows, causing out of sync
* issues.
*
* This could probably be done for full repaints also to simplify
* the client side.
*/
int pageBufferLastIndex = pageBufferFirstIndex
+ pageBuffer[CELL_ITEMID].length - 1;
target.addAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST,
pageBufferFirstIndex);
target.addAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST,
pageBufferLastIndex);
} else if (target.isFullRepaint() || isRowCacheInvalidated()) {
paintRows(target, cells, actionSet);
setRowCacheInvalidated(false);
@@ -2561,20 +2758,19 @@ public class Table extends AbstractSelect implements Action.Container,

target.startTag("prows");

int maxRows = (int) (getPageLength() * getCacheRate());
if (!shouldHideAddedRows() && count > maxRows) {
count = maxRows + 1;
// delete the rows below, since they will fall beyond the cache
// page.
target.addAttribute("delbelow", true);
}

target.addAttribute("firstprowix", firstIx);
target.addAttribute("numprows", count);

if (!shouldHideAddedRows()) {
logger.finest("Paint rows for add. Index: " + firstIx + ", count: "
+ count + ".");

// Partial row additions bypass the normal caching mechanism.
Object[][] cells = getVisibleCellsInsertIntoCache(firstIx, count);
if (cells[0].length < count) {
// delete the rows below, since they will fall beyond the cache
// page.
target.addAttribute("delbelow", true);
count = cells[0].length;
}

for (int indexInRowbuffer = 0; indexInRowbuffer < count; indexInRowbuffer++) {
final Object itemId = cells[CELL_ITEMID][indexInRowbuffer];
if (shouldHideNullSelectionItem()) {
@@ -2587,9 +2783,14 @@ public class Table extends AbstractSelect implements Action.Container,
indexInRowbuffer, itemId);
}
} else {
logger.finest("Paint rows for remove. Index: " + firstIx
+ ", count: " + count + ".");
removeRowsFromCacheAndFillBottom(firstIx, count);
target.addAttribute("hide", true);
}

target.addAttribute("firstprowix", firstIx);
target.addAttribute("numprows", count);
target.endTag("prows");
}

@@ -3251,6 +3452,9 @@ public class Table extends AbstractSelect implements Action.Container,

if (!actionHandlers.contains(actionHandler)) {
actionHandlers.add(actionHandler);
// Assures the visual refresh. No need to reset the page buffer
// before as the content has not changed, only the action
// handlers.
refreshRenderedCells();
}

@@ -3274,6 +3478,9 @@ public class Table extends AbstractSelect implements Action.Container,
actionMapper = null;
}

// Assures the visual refresh. No need to reset the page buffer
// before as the content has not changed, only the action
// handlers.
refreshRenderedCells();
}
}
@@ -3284,6 +3491,9 @@ public class Table extends AbstractSelect implements Action.Container,
public void removeAllActionHandlers() {
actionHandlers = null;
actionMapper = null;
// Assures the visual refresh. No need to reset the page buffer
// before as the content has not changed, only the action
// handlers.
refreshRenderedCells();
}

@@ -3302,13 +3512,17 @@ public class Table extends AbstractSelect implements Action.Container,
|| event.getProperty() == getPropertyDataSource()) {
super.valueChange(event);
} else {
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
containerChangeToBeRendered = true;
}
requestRepaint();
}

/**
* Clears the current page buffer. Call this before
* {@link #refreshRenderedCells()} to ensure that all content is updated
* from the properties.
*/
protected void resetPageBuffer() {
firstToBeRenderedInClient = -1;
lastToBeRenderedInClient = -1;
@@ -3378,8 +3592,7 @@ public class Table extends AbstractSelect implements Action.Container,
currentPageFirstItemId = nextItemId;
}
if (!(items instanceof Container.ItemSetChangeNotifier)) {
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
return ret;
}
@@ -3432,8 +3645,7 @@ public class Table extends AbstractSelect implements Action.Container,
return false;
}
if (!(items instanceof Container.PropertySetChangeNotifier)) {
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
return true;
}
@@ -3519,8 +3731,7 @@ public class Table extends AbstractSelect implements Action.Container,
if (!visibleColumns.contains(id)) {
visibleColumns.add(id);
}
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
}

@@ -3551,8 +3762,7 @@ public class Table extends AbstractSelect implements Action.Container,
if (!items.getContainerPropertyIds().contains(columnId)) {
visibleColumns.remove(columnId);
}
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
return true;
} else {
return false;
@@ -3611,8 +3821,7 @@ public class Table extends AbstractSelect implements Action.Container,
// (forced in this method)
setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false);

resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

/**
@@ -3739,8 +3948,7 @@ public class Table extends AbstractSelect implements Action.Container,
Object itemId = ((Container.Ordered) items)
.addItemAfter(previousItemId);
if (!(items instanceof Container.ItemSetChangeNotifier)) {
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
return itemId;
}
@@ -3756,8 +3964,7 @@ public class Table extends AbstractSelect implements Action.Container,
Item item = ((Container.Ordered) items).addItemAfter(previousItemId,
newItemId);
if (!(items instanceof Container.ItemSetChangeNotifier)) {
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}
return item;
}
@@ -3824,8 +4031,7 @@ public class Table extends AbstractSelect implements Action.Container,
this.fieldFactory = fieldFactory;

// Assure visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

/**
@@ -3867,8 +4073,7 @@ public class Table extends AbstractSelect implements Action.Container,
this.editable = editable;

// Assure visual refresh
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();
}

/**
@@ -3888,8 +4093,7 @@ public class Table extends AbstractSelect implements Action.Container,
final int pageIndex = getCurrentPageFirstItemIndex();
((Container.Sortable) c).sort(propertyId, ascending);
setCurrentPageFirstItemIndex(pageIndex);
resetPageBuffer();
refreshRenderedCells();
refreshRowCache();

} else if (c != null) {
throw new UnsupportedOperationException(
@@ -3960,7 +4164,8 @@ public class Table extends AbstractSelect implements Action.Container,

if (doSort) {
sort();
// Assures the visual refresh
// Assures the visual refresh. This should not be necessary as
// sort() calls refreshRowCache
refreshRenderedCells();
}
}
@@ -3998,10 +4203,11 @@ public class Table extends AbstractSelect implements Action.Container,
sortAscending = ascending;
if (doSort) {
sort();
// Assures the visual refresh. This should not be necessary as
// sort() calls refreshRowCache
refreshRenderedCells();
}
}
// Assures the visual refresh
refreshRenderedCells();
}

/**
@@ -4080,7 +4286,10 @@ public class Table extends AbstractSelect implements Action.Container,
*/
public void setCellStyleGenerator(CellStyleGenerator cellStyleGenerator) {
this.cellStyleGenerator = cellStyleGenerator;
// Assures the visual refresh. No need to reset the page buffer
// before as the content has not changed, only the style generators
refreshRenderedCells();

}

/**
@@ -4772,6 +4981,8 @@ public class Table extends AbstractSelect implements Action.Container,
public void setItemDescriptionGenerator(ItemDescriptionGenerator generator) {
if (generator != itemDescriptionGenerator) {
itemDescriptionGenerator = generator;
// Assures the visual refresh. No need to reset the page buffer
// before as the content has not changed, only the descriptions
refreshRenderedCells();
}
}
@@ -4899,7 +5110,7 @@ public class Table extends AbstractSelect implements Action.Container,
*/
public void setRowGenerator(RowGenerator generator) {
rowGenerator = generator;
refreshRenderedCells();
refreshRowCache();
}

/**

+ 21
- 1
src/com/vaadin/ui/TreeTable.java View File

@@ -11,6 +11,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import com.google.gwt.user.client.ui.Tree;
import com.vaadin.data.Container;
@@ -50,6 +51,9 @@ import com.vaadin.ui.treetable.HierarchicalContainerOrderedWrapper;
@ClientWidget(VTreeTable.class)
public class TreeTable extends Table implements Hierarchical {

private static final Logger logger = Logger.getLogger(TreeTable.class
.getName());

private interface ContainerStrategy extends Serializable {
public int size();

@@ -220,6 +224,9 @@ public class TreeTable extends Table implements Hierarchical {
boolean removed = openItems.remove(itemId);
if (!removed) {
openItems.add(itemId);
logger.finest("Item " + itemId + " is now expanded");
} else {
logger.finest("Item " + itemId + " is now collapsed");
}
clearPreorderCache();
}
@@ -312,6 +319,16 @@ public class TreeTable extends Table implements Hierarchical {
private ContainerStrategy cStrategy;
private Object focusedRowId = null;
private Object hierarchyColumnId;

/**
* The item id that was expanded or collapsed during this request. Reset at
* the end of paint and only used for determining if a partial or full paint
* should be done.
*
* Can safely be reset to null whenever a change occurs that would prevent a
* partial update from rendering the correct result, e.g. rows added or
* removed during an expand operation.
*/
private Object toggledItemId;
private boolean animationsEnabled;
private boolean clearFocusedRowPending;
@@ -361,6 +378,7 @@ public class TreeTable extends Table implements Hierarchical {
if (variables.containsKey("toggleCollapsed")) {
String object = (String) variables.get("toggleCollapsed");
Object itemId = itemIdMapper.get(object);
toggledItemId = itemId;
toggleChildVisibility(itemId);
if (variables.containsKey("selectCollapsed")) {
// ensure collapsed is selected unless opened with selection
@@ -497,7 +515,6 @@ public class TreeTable extends Table implements Hierarchical {
// ensure that page still has first item in page, DON'T clear the
// caches.
setCurrentPageFirstItemIndex(getCurrentPageFirstItemIndex(), false);
toggledItemId = itemId;
requestRepaint();

if (isCollapsed(itemId)) {
@@ -535,6 +552,9 @@ public class TreeTable extends Table implements Hierarchical {
@Override
public void containerItemSetChange(
com.vaadin.data.Container.ItemSetChangeEvent event) {
// Can't do partial repaints if items are added or removed during the
// expand/collapse request
toggledItemId = null;
getContainerStrategy().containerItemSetChange(event);
super.containerItemSetChange(event);
}

+ 3
- 1
tests/integration_base_files/base.xml View File

@@ -58,6 +58,8 @@
<waitfor maxwait="${waitMinutes}" maxwaitunit="minute" checkevery="10000" timeoutproperty="timeout">
<http url="${waitUrl}" />
</waitfor>
<!-- Print load averages to get an indicator on whether the server still attempts to start up -->
<exec executable="uptime" />
<fail if="timeout" message="${server} failed to deploy" />

<echo message="${server}: Demo deployed successfully." />
@@ -101,7 +103,7 @@
</target>
<target name="clean">
<delete dir="${deployDir}" />
<delete dir="${deployDir}" failonerror="false" />
</target>
<target name="release-lock">

+ 11
- 3
tests/integration_tests.xml View File

@@ -348,11 +348,19 @@
<scp file="${demo.war}" todir="${user}@${target-host}:demo.war" keyfile="${sshkey.file}" trust="yes" passphrase="${passphrase}" />
<!-- timeout in 15 minutes -->
<sshexec host="${target-host}" outputproperty="start-output" timeout="900000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml startup-and-deploy" />
<sshexec host="${target-host}" outputproperty="start-output" timeout="900000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml startup-and-deploy" failonerror="false" />
<antcall target="echo-prefix">
<param name="prefix" value="${target-server}: " />
<param name="message" value="${start-output}" />
</antcall>
<fail message="${start-output}">
<condition>
<not>
<contains string="${start-output}" substring="Demo deployed successfully" />
</not>
</condition>
</fail>
<copy file="integration-testscripts/common/integration_test.tpl" tofile="integration-testscripts/integration-test-${target-server}-servlet.html" overwrite="true" />
<antcall target="integration-test-servlet">
@@ -376,7 +384,7 @@
</catch>
<finally>
<!-- timeout in five minutes -->
<sshexec host="${target-host}" outputproperty="stop-output" timeout="300000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml shutdown-and-cleanup" />
<sshexec host="${target-host}" outputproperty="stop-output" timeout="300000" username="${user}" keyfile="${sshkey.file}" trust="yes" command="ant -f deploy.xml shutdown-and-cleanup" failonerror="false" />
<antcall target="echo-prefix">
<param name="prefix" value="${target-server}: " />
<param name="message" value="${stop-output}" />
@@ -448,4 +456,4 @@
<target name="integration-test-clean">
<sshexec host="${test.integration.server}" username="${user}" keyfile="${sshkey.file}" command="ant -f ${ant.hub} clean" />
</target>
</project>
</project>

+ 16
- 0
tests/server-side/com/vaadin/data/util/FileSystemContainerTest.java View File

@@ -0,0 +1,16 @@
package com.vaadin.data.util;

import java.io.File;

import org.junit.Assert;
import org.junit.Test;

public class FileSystemContainerTest {

@Test
public void nonExistingDirectory() {
FilesystemContainer fsc = new FilesystemContainer(new File(
"/non/existing"));
Assert.assertTrue(fsc.getItemIds().isEmpty());
}
}

+ 1
- 1
tests/test.xml View File

@@ -205,4 +205,4 @@
<target name="test-package" depends="server-start, run-and-clean-up, server-stop">
</target>

</project>
</project>

+ 0
- 6
tests/testbench/com/vaadin/tests/application/WebBrowserTest.html View File

@@ -39,12 +39,6 @@
<td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VLabel[0]</td>
<td>Yes</td>
</tr>
<!-- DST active? -->
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td>
<td>Yes</td>
</tr>
</tbody></table>
</body>
</html>

+ 0
- 0
tests/testbench/com/vaadin/tests/components/combobox/fi.gif View File


+ 0
- 0
tests/testbench/com/vaadin/tests/components/combobox/se.gif View File


+ 0
- 0
tests/testbench/com/vaadin/tests/components/menubar/MenuBarRunsOutOfBrowser.html View File


+ 0
- 0
tests/testbench/com/vaadin/tests/components/table/fi.gif View File


+ 0
- 0
tests/testbench/com/vaadin/tests/components/table/se.gif View File


+ 92
- 0
tests/testbench/com/vaadin/tests/components/treetable/DynamicallyModified.html View File

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.treetable.DynamicallyModified?restartApplication</td>
<td></td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>initial</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td>
<td>47,5</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>proj1-collapsed</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td>
<td>48,8</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>proj1-two-children</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]/domChild[0]</td>
<td>49,7</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>proj2-collapsed</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]/domChild[0]</td>
<td>47,7</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>proj2-three-children</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]/domChild[0]</td>
<td>45,4</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[5]/domChild[0]/domChild[0]/domChild[0]</td>
<td>45,4</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td>
<td>48,6</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableDynamicallyModified::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]</td>
<td>48,6</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>proj1-one-child-proj2-four-children</td>
</tr>

</tbody></table>
</body>
</html>

+ 125
- 113
tests/testbench/com/vaadin/tests/components/treetable/DynamicallyModified.java View File

@@ -1,113 +1,125 @@
package com.vaadin.tests.components.treetable;

import java.util.Calendar;
import java.util.Collection;
import java.util.Date;

import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.Tree;
import com.vaadin.ui.Tree.CollapseEvent;
import com.vaadin.ui.Tree.ExpandEvent;
import com.vaadin.ui.TreeTable;

public class DynamicallyModified extends TestBase implements
Tree.ExpandListener, Tree.CollapseListener {
protected static final String NAME_PROPERTY = "Name";
protected static final String HOURS_PROPERTY = "Hours done";
protected static final String MODIFIED_PROPERTY = "Last Modified";

protected TreeTable treetable;

@Override
protected void setup() {
getLayout().setWidth("100%");

// Calendar
Calendar cal = Calendar.getInstance();
cal.set(2011, 10, 30, 14, 40, 26);

// Create the treetable
treetable = new TreeTable();
treetable.setWidth("100%");
treetable.addListener((Tree.ExpandListener) this);
treetable.addListener((Tree.CollapseListener) this);

addComponent(treetable);

// Add Table columns
treetable.addContainerProperty(NAME_PROPERTY, String.class, "");
treetable.addContainerProperty(HOURS_PROPERTY, Integer.class, 0);
treetable.addContainerProperty(MODIFIED_PROPERTY, Date.class,
cal.getTime());

// Populate table
Object allProjects = treetable.addItem(new Object[] { "All Projects",
18, cal.getTime() }, null);
Object year2010 = treetable.addItem(
new Object[] { "Year 2010", 18, cal.getTime() }, null);
Object customerProject1 = treetable.addItem(new Object[] {
"Customer Project 1", 13, cal.getTime() }, null);
Object customerProject1Implementation = treetable.addItem(new Object[] {
"Implementation", 5, cal.getTime() }, null);
Object customerProject1Planning = treetable.addItem(new Object[] {
"Planning", 2, cal.getTime() }, null);
Object customerProject1Prototype = treetable.addItem(new Object[] {
"Prototype", 5, cal.getTime() }, null);
Object customerProject2 = treetable.addItem(new Object[] {
"Customer Project 2", 5, cal.getTime() }, null);
Object customerProject2Planning = treetable.addItem(new Object[] {
"Planning", 5, cal.getTime() }, null);

// Set hierarchy
treetable.setParent(year2010, allProjects);
treetable.setParent(customerProject1, year2010);
treetable.setParent(customerProject1Implementation, customerProject1);
treetable.setParent(customerProject1Planning, customerProject1);
treetable.setParent(customerProject1Prototype, customerProject1);
treetable.setParent(customerProject2, year2010);
treetable.setParent(customerProject2Planning, customerProject2);

// Disallow children from leaves
treetable.setChildrenAllowed(customerProject1Implementation, false);
treetable.setChildrenAllowed(customerProject1Planning, false);
treetable.setChildrenAllowed(customerProject1Prototype, false);
treetable.setChildrenAllowed(customerProject2Planning, false);

// Expand all
treetable.setCollapsed(allProjects, false);
treetable.setCollapsed(year2010, false);
treetable.setCollapsed(customerProject1, false);
treetable.setCollapsed(customerProject2, false);
}

@Override
protected String getDescription() {
return "Expanding and collapsing nodes should actually expand and collapse them even when modifying the container in a collapse listener.";
}

@Override
protected Integer getTicketNumber() {
return 7780;
}

public void nodeExpand(ExpandEvent event) {

}

public void nodeCollapse(CollapseEvent event) {

Collection<Object> childs = (Collection<Object>) treetable
.getChildren(event.getItemId());

if (childs == null) {
return;
}
Object[] arr = childs.toArray();

for (Object obj : arr) {
System.out.println("remove " + obj.toString());
treetable.removeItem(obj);
}

}
}
package com.vaadin.tests.components.treetable;
import java.util.Collection;
import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.Tree;
import com.vaadin.ui.Tree.CollapseEvent;
import com.vaadin.ui.Tree.ExpandEvent;
import com.vaadin.ui.TreeTable;
public class DynamicallyModified extends TestBase implements
Tree.ExpandListener, Tree.CollapseListener {
protected static final String NAME_PROPERTY = "Name";
protected static final String HOURS_PROPERTY = "Hours done";
protected static final String MODIFIED_PROPERTY = "Last Modified";
private static final String DEFAULT_DATE = "Wed Nov 30 14:40:26 EET 2011";
protected TreeTable treetable;
@Override
protected void setup() {
getLayout().setWidth("100%");
// Create the treetable
treetable = new TreeTable();
treetable.setWidth("100%");
treetable.addListener((Tree.ExpandListener) this);
treetable.addListener((Tree.CollapseListener) this);
addComponent(treetable);
// Add Table columns
treetable.addContainerProperty(NAME_PROPERTY, String.class, "");
treetable.addContainerProperty(HOURS_PROPERTY, Integer.class, 0);
treetable.addContainerProperty(MODIFIED_PROPERTY, String.class,
DEFAULT_DATE);
// Populate table
Object allProjects = treetable.addItem(new Object[] { "All Projects",
18, DEFAULT_DATE }, null);
Object year2010 = treetable.addItem(new Object[] { "Year 2010", 18,
DEFAULT_DATE }, null);
Object customerProject1 = treetable.addItem(new Object[] {
"Customer Project 1", 13, DEFAULT_DATE }, null);
Object customerProject1Implementation = treetable.addItem(new Object[] {
"Implementation", 5, DEFAULT_DATE }, null);
Object customerProject1Planning = treetable.addItem(new Object[] {
"Planning", 2, DEFAULT_DATE }, null);
Object customerProject1Prototype = treetable.addItem(new Object[] {
"Prototype", 5, DEFAULT_DATE }, null);
Object customerProject2 = treetable.addItem(new Object[] {
"Customer Project 2", 5, DEFAULT_DATE }, null);
Object customerProject2Planning = treetable.addItem(new Object[] {
"Planning", 5, DEFAULT_DATE }, null);
// Set hierarchy
treetable.setParent(year2010, allProjects);
treetable.setParent(customerProject1, year2010);
treetable.setParent(customerProject1Implementation, customerProject1);
treetable.setParent(customerProject1Planning, customerProject1);
treetable.setParent(customerProject1Prototype, customerProject1);
treetable.setParent(customerProject2, year2010);
treetable.setParent(customerProject2Planning, customerProject2);
// Disallow children from leaves
treetable.setChildrenAllowed(customerProject1Implementation, false);
treetable.setChildrenAllowed(customerProject1Planning, false);
treetable.setChildrenAllowed(customerProject1Prototype, false);
treetable.setChildrenAllowed(customerProject2Planning, false);
// Expand all
treetable.setCollapsed(allProjects, false);
treetable.setCollapsed(year2010, false);
treetable.setCollapsed(customerProject1, false);
treetable.setCollapsed(customerProject2, false);
}
@Override
protected String getDescription() {
return "Collaps 'Customer Project 1' will cause the first child if it to be removed. Expanding 'Custom Project 2' will cause a new child to be added. These events should be rendered correctly.";
}
@Override
protected Integer getTicketNumber() {
return 7780;
}
private int newChild = 1;
public void nodeExpand(ExpandEvent event) {
Object expandedItemId = event.getItemId();
// 7 == "Customer Project 1"
if (expandedItemId != Integer.valueOf(7)) {
return;
}
Object newChildId = treetable.addItem(new Object[] {
"New child " + newChild++, 5, "Fri Nov 04 10:53:16 EET 2011" },
null);
treetable.setParent(newChildId, expandedItemId);
treetable.setChildrenAllowed(newChildId, false);
}
public void nodeCollapse(CollapseEvent event) {
Object collapsedItemId = event.getItemId();
// 3 == "Customer Project 1"
if (collapsedItemId != Integer.valueOf(3)) {
return;
}
@SuppressWarnings("unchecked")
Collection<Object> childs = (Collection<Object>) treetable
.getChildren(event.getItemId());
if (childs == null) {
return;
}
Object[] arr = childs.toArray();
if (arr.length > 0) {
treetable.removeItem(arr[0]);
}
}
}

+ 528
- 0
tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdate.html View File

@@ -0,0 +1,528 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.treetable.TreeTableCacheOnPartialUpdates?restartApplication</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
<td>47,5</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VNativeButton[0]</td>
<td>46,7</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[6]/VNativeButton[0]</td>
<td>54,12</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>1. Button Item TestBean [col1=1 (children), col2=A]/col3 clicked. Row index: 0</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>2. Button Item TestBean [col1=2, col2=B]/col3 clicked. Row index: 1</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>3. Button Item TestBean [col1=7 (children), col2=G]/col3 clicked. Row index: 6</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
<td>10,7</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>4. Row Item TestBean [col1=1 (children), col2=A] expanded. Row index: 0</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
<td>81,6</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VNativeButton[0]</td>
<td>73,8</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
<td>86,7</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[5]/VNativeButton[0]</td>
<td>72,2</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[6]/VNativeButton[0]</td>
<td>73,7</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_4</td>
<td>5. Button Item TestBean [col1=1 (children), col2=A]/col3 clicked. Row index: 0</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td>
<td>6. Button Item TestBean [col1=1.1, col2=A.A]/col3 clicked. Row index: 1</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>7. Button Item TestBean [col1=1 (children), col2=A]/col3 clicked. Row index: 0</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>8. Button Item TestBean [col1=1.5, col2=A.E]/col3 clicked. Row index: 5</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>9. Button Item TestBean [col1=2, col2=B]/col3 clicked. Row index: 6</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
<td>11,2</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>10. Row Item TestBean [col1=1 (children), col2=A] collapsed. Row index: 0</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
<td>76,5</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[2]/VNativeButton[0]</td>
<td>58,7</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[1]/VNativeButton[0]</td>
<td>69,10</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[0]/VNativeButton[0]</td>
<td>78,7</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_4</td>
<td>10. Row Item TestBean [col1=1 (children), col2=A] collapsed. Row index: 0</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td>
<td>11. Button Item TestBean [col1=1 (children), col2=A]/col3 clicked. Row index: 0</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>12. Button Item TestBean [col1=3 (children), col2=C]/col3 clicked. Row index: 2</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>13. Button Item TestBean [col1=2, col2=B]/col3 clicked. Row index: 1</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>14. Button Item TestBean [col1=1 (children), col2=A]/col3 clicked. Row index: 0</td>
</tr>
<tr>
<td>scroll</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]</td>
<td>30000</td>
</tr>
<tr>
<td>pause</td>
<td>500</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[41]/VNativeButton[0]</td>
<td>53,-2462</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
<td>91,-2452</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[28]/VNativeButton[0]</td>
<td>84,-2461</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[41]/VNativeButton[0]</td>
<td>102,-2452</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td>
<td>15. Button Item TestBean [col1=100, col2=CV]/col3 clicked. Row index: 99</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>16. Button Item TestBean [col1=93, col2=CO]/col3 clicked. Row index: 92</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>17. Button Item TestBean [col1=87, col2=CI]/col3 clicked. Row index: 86</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>18. Button Item TestBean [col1=100, col2=CV]/col3 clicked. Row index: 99</td>
</tr>
<!-- This relies on the row height being the same in all browsers. -->
<tr>
<td>scroll</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]</td>
<td>990</td>
</tr>
<tr>
<td>pause</td>
<td>500</td>
<td></td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>scrolled</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
<td>34,-994</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[34]/domChild[0]/domChild[0]/domChild[0]</td>
<td>9,-995</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
<td>93,-991</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[35]/VNativeButton[0]</td>
<td>123,-991</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
<td>114,-1000</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
<td>118,-993</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_4</td>
<td>20. Row Item TestBean [col1=40 (children), col2=AN] expanded. Row index: 39</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td>
<td>21. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>22. Button Item TestBean [col1=40.1, col2=AN.A]/col3 clicked. Row index: 40</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>23. Button Item TestBean [col1=40.10, col2=AN.J]/col3 clicked. Row index: 49</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>24. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[34]/domChild[0]/domChild[0]/domChild[0]</td>
<td>9,-998</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[34]/VNativeButton[0]</td>
<td>42,-990</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[29]/VNativeButton[0]</td>
<td>84,-990</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
<td>98,-998</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>26. Button Item TestBean [col1=40 (children), col2=AN]/col3 clicked. Row index: 39</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>27. Button Item TestBean [col1=35, col2=AI]/col3 clicked. Row index: 34</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>28. Button Item TestBean [col1=48, col2=AV]/col3 clicked. Row index: 47</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[35]/VNativeButton[0]</td>
<td>101,-994</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>29. Button Item TestBean [col1=41, col2=AO]/col3 clicked. Row index: 40</td>
</tr>
<tr>
<td>scroll</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]</td>
<td>2465</td>
</tr>
<tr>
<td>pause</td>
<td>500</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[30]/VNativeButton[0]</td>
<td>136,-2447</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
<td>131,-2462</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
<td>134,-2459</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
<td>144,-2454</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td>
<td>30. Button Item TestBean [col1=86, col2=CH]/col3 clicked. Row index: 85</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>31. Button Item TestBean [col1=98, col2=CT]/col3 clicked. Row index: 97</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>32. Button Item TestBean [col1=99 (children), col2=CU]/col3 clicked. Row index: 98</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>33. Button Item TestBean [col1=100, col2=CV]/col3 clicked. Row index: 99</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[43]/domChild[0]/domChild[0]/domChild[0]</td>
<td>10,-2461</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
<td>65,-2456</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>34. Row Item TestBean [col1=99 (children), col2=CU] expanded. Row index: 98</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>35. Button Item TestBean [col1=99 (children), col2=CU]/col3 clicked. Row index: 98</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[30]/VNativeButton[0]</td>
<td>109,-2455</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>36. Button Item TestBean [col1=86, col2=CH]/col3 clicked. Row index: 85</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
<td>82,-2457</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>37. Button Item TestBean [col1=99.1, col2=CU.A]/col3 clicked. Row index: 99</td>
</tr>
<tr>
<td>scroll</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]</td>
<td>2800</td>
</tr>
<tr>
<td>pause</td>
<td>500</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
<td>85,-2792</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
<td>101,-2788</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
<td>111,-2794</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[56]/VNativeButton[0]</td>
<td>113,-2794</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_3</td>
<td>38. Button Item TestBean [col1=99 (children), col2=CU]/col3 clicked. Row index: 98</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_2</td>
<td>39. Button Item TestBean [col1=98, col2=CT]/col3 clicked. Row index: 97</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_1</td>
<td>40. Button Item TestBean [col1=99.1, col2=CU.A]/col3 clicked. Row index: 99</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>41. Button Item TestBean [col1=99.13, col2=CU.M]/col3 clicked. Row index: 111</td>
</tr>
<!--collapse 99-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[43]/domChild[0]/domChild[0]/domChild[0]</td>
<td>11,-2792</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>42. Row Item TestBean [col1=99 (children), col2=CU] collapsed. Row index: 98</td>
</tr>
<tr>
<td>pause</td>
<td></td>
<td>300</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[43]/VNativeButton[0]</td>
<td>71,-2465</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>43. Button Item TestBean [col1=99 (children), col2=CU]/col3 clicked. Row index: 98</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[44]/VNativeButton[0]</td>
<td>81,-2459</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>44. Button Item TestBean [col1=100, col2=CV]/col3 clicked. Row index: 99</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[42]/VNativeButton[0]</td>
<td>80,-2458</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>45. Button Item TestBean [col1=98, col2=CT]/col3 clicked. Row index: 97</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VTreeTable[0]/FocusableScrollPanel[0]/VTreeTable$VTreeTableScrollBody[0]/VTreeTable$VTreeTableScrollBody$VTreeTableRow[30]/VNativeButton[0]</td>
<td>86,-2462</td>
</tr>
<tr>
<td>assertText</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTableCacheOnPartialUpdates::PID_SLog_row_0</td>
<td>46. Button Item TestBean [col1=86, col2=CH]/col3 clicked. Row index: 85</td>
</tr>
</tbody></table>
</body>
</html>

+ 238
- 0
tests/testbench/com/vaadin/tests/components/treetable/TreeTableCacheOnPartialUpdates.java View File

@@ -0,0 +1,238 @@
package com.vaadin.tests.components.treetable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.vaadin.data.Container;
import com.vaadin.data.Container.Ordered;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.ContainerHierarchicalWrapper;
import com.vaadin.tests.components.TestBase;
import com.vaadin.tests.util.Log;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.Tree.CollapseEvent;
import com.vaadin.ui.Tree.CollapseListener;
import com.vaadin.ui.Tree.ExpandEvent;
import com.vaadin.ui.Tree.ExpandListener;
import com.vaadin.ui.TreeTable;
public class TreeTableCacheOnPartialUpdates extends TestBase {
private Log log = new Log(5);
public class TestBean implements Serializable {
private String col1;
private String col2;
public TestBean() {
col1 = "";
col2 = "";
}
public TestBean(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
@Override
public String toString() {
return "TestBean [col1=" + col1 + ", col2=" + col2 + "]";
}
}
public class Col3ColumnGenerator implements ColumnGenerator {
public Component generateCell(final com.vaadin.ui.Table source,
final Object itemId, Object columnId) {
TestBean tb = (TestBean) itemId;
// if (!tb.getCol1().contains("children")) {
// return null;
// }
String identifier = "Item " + itemId + "/" + columnId;
System.out.println("Generating new Button for " + identifier);
Button btnCol3 = new NativeButton(identifier);
btnCol3.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
log.log("Button " + event.getButton().getCaption()
+ " clicked. Row index: "
+ indexOfId(source, itemId));
}
});
return btnCol3;
}
}
protected int indexOfId(Table source, Object itemId) {
Container.Ordered c = (Ordered) source.getContainerDataSource();
if (c instanceof Container.Indexed) {
return ((Container.Indexed) source).indexOfId(itemId);
} else {
ArrayList<Object> list = new ArrayList<Object>(source.getItemIds());
return list.indexOf(itemId);
}
}
private TreeTable treeTable;
private BeanItemContainer<TestBean> testBeanContainer;
private static String[] columnHeaders = new String[] { "Col1", "Col2",
"Col3" };
private static Object[] visibleColumns = new Object[] { "col1", "col2",
"col3" };
@Override
public void setup() {
setTheme("reindeer-tests");
// Force row height to be the same in all browsers so scrolling based on
// pixels works as expected
Button b = new Button("Show first");
addComponent(b);
b.addListener(new ClickListener() {
public void buttonClick(ClickEvent event) {
log.log("First visible item id is: "
+ treeTable.getCurrentPageFirstItemId());
}
});
NativeSelect cacheRateSelect = new NativeSelect("Cache rate");
cacheRateSelect.setImmediate(true);
cacheRateSelect.setNullSelectionAllowed(false);
cacheRateSelect.addItem(new Integer(0));
cacheRateSelect.addItem(new Integer(1));
cacheRateSelect.addItem(new Integer(2));
cacheRateSelect.setValue(2);
cacheRateSelect.addListener(new ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
treeTable
.setCacheRate((Integer) event.getProperty().getValue());
}
});
addComponent(cacheRateSelect);
treeTable = new TreeTable();
treeTable.addStyleName("table-equal-rowheight");
// treeTable.setPageLength(0);
testBeanContainer = new BeanItemContainer<TestBean>(TestBean.class);
Map<String, Integer> hasChildren = new HashMap<String, Integer>();
hasChildren.put("1", 5);
hasChildren.put("3", 10);
hasChildren.put("5", 20);
hasChildren.put("6", 7);
hasChildren.put("7", 1);
hasChildren.put("40", 20);
hasChildren.put("99", 20);
treeTable.setContainerDataSource(createContainer(100, hasChildren));
treeTable.addGeneratedColumn("col3", new Col3ColumnGenerator());
treeTable.addListener(new ExpandListener() {
public void nodeExpand(ExpandEvent event) {
logExpandCollapse(event.getItemId(), "expanded");
}
});
treeTable.addListener(new CollapseListener() {
public void nodeCollapse(CollapseEvent event) {
logExpandCollapse(event.getItemId(), "collapsed");
}
});
treeTable.setColumnHeaders(columnHeaders);
treeTable.setVisibleColumns(visibleColumns);
treeTable.setColumnWidth("col1", 150);
treeTable.setColumnWidth("col2", 50);
treeTable.setHeight("430px");
// treeTable.setColumnWidth("col3", 150);
addComponent(log);
addComponent(treeTable);
}
protected void logExpandCollapse(Object itemId, String operation) {
String identifier = "Item " + itemId;
log.log("Row " + identifier + " " + operation + ". Row index: "
+ indexOfId(treeTable, itemId));
}
private Container createContainer(int items,
Map<String, Integer> hasChildren) {
ContainerHierarchicalWrapper container;
container = new ContainerHierarchicalWrapper(testBeanContainer);
populate(container, items, hasChildren);
return container;
}
private void populate(Container.Hierarchical container, int items,
Map<String, Integer> children) {
for (int i = 0; i < items; i++) {
String row = String.valueOf(i + 1);
String rowText = stringForInt(i);
TestBean itemId = new TestBean(row, rowText);
container.addItem(itemId);
if (children.containsKey(row)) {
itemId.setCol1(itemId.getCol1() + " (children)");
for (int j = 0; j < children.get(row); j++) {
TestBean childItemId = new TestBean(row + "." + (j + 1),
rowText + "." + stringForInt(j));
container.addItem(childItemId);
container.setParent(childItemId, itemId);
}
}
}
}
private String stringForInt(int i) {
int charsAllowed = 26; // a-z
if (i >= charsAllowed) {
return stringForInt(i / charsAllowed - 1)
+ stringForInt(i % charsAllowed);
} else {
return String.valueOf((char) (i + 'A'));
}
}
@Override
protected String getDescription() {
// TODO Auto-generated method stub
return null;
}
@Override
protected Integer getTicketNumber() {
// TODO Auto-generated method stub
return null;
}
}

+ 55
- 0
tests/testbench/com/vaadin/tests/components/treetable/TreeTableNegativeArraySize.html View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.treetable.TreeTablePartialUpdates?restartApplication</td>
<td></td>
</tr>
<!--expand root1-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
<td>12,4</td>
</tr>
<tr>
<td>scroll</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]</td>
<td>3969</td>
</tr>
<tr>
<td>pause</td>
<td>300</td>
<td></td>
</tr>
<!--expand root2-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[42]/domChild[0]/domChild[0]/domChild[0]</td>
<td>9,-183</td>
</tr>
<!--collapse root2-->
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdates::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[42]/domChild[0]/domChild[0]/domChild[0]</td>
<td>11,-182</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>root1-expanded-scrolled-to-end</td>
</tr>

</tbody></table>
</body>
</html>

+ 56
- 0
tests/testbench/com/vaadin/tests/components/treetable/TreeTablePartialUpdatesPageLength0.html View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>DisappearingComponents</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">DisappearingComponents</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>/run/com.vaadin.tests.components.treetable.TreeTablePartialUpdatesPageLength0?restartApplication</td>
<td></td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdatesPageLength0::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td>
<td>10,2</td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>root1-expanded-10-items</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdatesPageLength0::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[12]/domChild[0]/domChild[0]/domChild[0]</td>
<td>11,3</td>
</tr>
<tr>
<td>mouseClick</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdatesPageLength0::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VTreeTable[0]/domChild[1]/domChild[0]/domChild[1]/domChild[0]/domChild[11]/domChild[0]/domChild[0]/domChild[0]</td>
<td>9,7</td>
</tr>
<tr>
<td>scroll</td>
<td>vaadin=runcomvaadintestscomponentstreetableTreeTablePartialUpdatesPageLength0::</td>
<td>11771</td>
</tr>
<tr>
<td>pause</td>
<td>300</td>
<td></td>
</tr>
<tr>
<td>screenCapture</td>
<td></td>
<td>all-expanded-bottom</td>
</tr>
</tbody></table>
</body>
</html>

+ 68
- 0
tests/testbench/com/vaadin/tests/components/treetable/TreeTablePartialUpdatesPageLength0.java View File

@@ -0,0 +1,68 @@
package com.vaadin.tests.components.treetable;

import com.vaadin.data.Container.Hierarchical;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.tests.components.TestBase;
import com.vaadin.ui.TreeTable;

public class TreeTablePartialUpdatesPageLength0 extends TestBase {

@Override
protected void setup() {
setTheme("reindeer-tests");
TreeTable tt = new TreeTable();
tt.addStyleName("table-equal-rowheight");
tt.setPageLength(0);
tt.setContainerDataSource(makeHierarchicalContainer());
tt.setWidth("300px");
addComponent(tt);
tt.getParent().setHeight(null);
tt.getParent().getParent().setHeight(null);
}

private Hierarchical makeHierarchicalContainer() {
HierarchicalContainer hc = new HierarchicalContainer();
hc.addContainerProperty("p1", String.class, "");
hc.addContainerProperty("p2", String.class, "");

Object r1 = hc.addItem();
hc.getItem(r1).getItemProperty("p1").setValue("root1");
hc.getItem(r1).getItemProperty("p2").setValue("root1");

Object r2 = hc.addItem();
hc.getItem(r2).getItemProperty("p1").setValue("root2");
hc.getItem(r2).getItemProperty("p2").setValue("root2");

Object r3 = hc.addItem();
hc.getItem(r3).getItemProperty("p1").setValue("root3");
hc.getItem(r3).getItemProperty("p2").setValue("root3");

Object r4 = hc.addItem();
hc.getItem(r4).getItemProperty("p1").setValue("END");
hc.setChildrenAllowed(r4, false);

addNodesToRoot(hc, r1, 10);
addNodesToRoot(hc, r2, 200);
addNodesToRoot(hc, r3, 200);
return hc;
}

private void addNodesToRoot(HierarchicalContainer hc, Object root, int count) {
for (int ix = 0; ix < count; ix++) {
Object id = hc.addItem();
hc.getItem(id).getItemProperty("p1").setValue(String.valueOf(ix));
hc.setParent(id, root);
}
}

@Override
protected String getDescription() {
return "";
}

@Override
protected Integer getTicketNumber() {
return 6722;
}

}

+ 58
- 0
tests/testbench/com/vaadin/tests/components/upload/TestFileUpload.java View File

@@ -0,0 +1,58 @@
package com.vaadin.tests.components.upload;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import org.apache.commons.codec.digest.DigestUtils;
import com.vaadin.tests.components.TestBase;
import com.vaadin.tests.util.Log;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FinishedEvent;
import com.vaadin.ui.Upload.Receiver;
public class TestFileUpload extends TestBase implements Receiver {
private Log log = new Log(5);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@Override
protected void setup() {
Upload u = new Upload("Upload", new Upload.Receiver() {
public OutputStream receiveUpload(String filename, String mimeType) {
return baos;
}
});
u.setDebugId("UPL");
u.addListener(new Upload.FinishedListener() {
public void uploadFinished(FinishedEvent event) {
String hash = DigestUtils.md5Hex(baos.toByteArray());
log.log("Upload finished. Name: " + event.getFilename()
+ ", Size: " + baos.size() + ", md5: " + hash);
baos.reset();
}
});
addComponent(log);
addComponent(u);
}
public OutputStream receiveUpload(String filename, String MIMEType) {
getMainWindow().showNotification("Receiving upload");
return new ByteArrayOutputStream();
}
@Override
protected Integer getTicketNumber() {
return 6465;
}
@Override
protected String getDescription() {
return "Creates and prints an MD5 hash of any uploaded file.";
}
}

BIN
tests/testbench/com/vaadin/tests/components/upload/file-binary-cb4a65687deb859957ad4b0fd9d67eac.png View File


+ 1004
- 0
tests/testbench/com/vaadin/tests/components/upload/file-text-6ebed606225d0b6254d45f51aa2dfe9f
File diff suppressed because it is too large
View File


+ 0
- 0
tests/testbench/com/vaadin/tests/integration/fi.gif View File


+ 0
- 0
tests/testbench/com/vaadin/tests/integration/se.gif View File


Loading…
Cancel
Save