diff options
79 files changed, 2401 insertions, 197 deletions
diff --git a/client/src/main/java/com/vaadin/client/AnimationUtil.java b/client/src/main/java/com/vaadin/client/AnimationUtil.java index bbefcffbdd..e2cf9e690a 100644 --- a/client/src/main/java/com/vaadin/client/AnimationUtil.java +++ b/client/src/main/java/com/vaadin/client/AnimationUtil.java @@ -19,7 +19,6 @@ import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Style; -import com.vaadin.client.AnimationUtil.AnimationEndListener; /** * Utility methods for working with CSS transitions and animations. @@ -67,15 +66,15 @@ public class AnimationUtil { listener.@com.vaadin.client.AnimationUtil.AnimationEndListener::onAnimationEnd(Lcom/google/gwt/dom/client/NativeEvent;)(e); }); callbackFunc.listener = listener; - + elem.addEventListener(@com.vaadin.client.AnimationUtil::ANIMATION_END_EVENT_NAME, callbackFunc, false); - + // Store function reference for later removal if(!elem._vaadin_animationend_callbacks) { elem._vaadin_animationend_callbacks = []; } elem._vaadin_animationend_callbacks.push(callbackFunc); - + return callbackFunc; }-*/; @@ -138,7 +137,7 @@ public class AnimationUtil { return event.mozAnimationName; else if(event.oAnimationName) return event.oAnimationName; - + return ""; }-*/; @@ -146,22 +145,22 @@ public class AnimationUtil { public static native String getAnimationName(ComputedStyle cstyle) /*-{ var cs = cstyle.@com.vaadin.client.ComputedStyle::computedStyle; - + if(!cs.getPropertyValue) return ""; - + if(cs.getPropertyValue("-webkit-animation-name")) return cs.getPropertyValue("-webkit-animation-name"); - + else if(cs.getPropertyValue("animation-name")) return cs.getPropertyValue("animation-name"); - + else if(cs.getPropertyValue("-moz-animation-name")) return cs.getPropertyValue("-moz-animation-name"); - + else if(cs.getPropertyValue("-o-animation-name")) return cs.getPropertyValue("-o-animation-name"); - + return ""; }-*/; @@ -176,7 +175,7 @@ public class AnimationUtil { 'MozAnimation': 'animationend', 'WebkitAnimation': 'webkitAnimationEnd' } - + for(var a in anims){ if( el.style[a] !== undefined ){ return anims[a]; @@ -195,7 +194,7 @@ public class AnimationUtil { 'mozAnimation', 'webkitAnimation' ] - + for(var i=0; i < anims.length; i++) { if( el.style[anims[i]] !== undefined ){ return anims[i]; diff --git a/client/src/main/java/com/vaadin/client/LayoutManager.java b/client/src/main/java/com/vaadin/client/LayoutManager.java index 841eead561..ad0a3f8c38 100644 --- a/client/src/main/java/com/vaadin/client/LayoutManager.java +++ b/client/src/main/java/com/vaadin/client/LayoutManager.java @@ -600,6 +600,14 @@ public class LayoutManager { } Profiler.leave("layout PostLayoutListener"); + // Ensure temporary variables are cleaned + if (!pendingOverflowFixes.isEmpty()) { + getLogger().warning( + "pendingOverflowFixes is not empty at the end of doLayout: " + + pendingOverflowFixes.dump()); + pendingOverflowFixes = FastStringSet.create(); + } + getLogger().info("Total layout phase time: " + totalDuration.elapsedMillis() + "ms"); } diff --git a/client/src/main/java/com/vaadin/client/communication/ServerRpcQueue.java b/client/src/main/java/com/vaadin/client/communication/ServerRpcQueue.java index 35d6f48565..ce07fc0baf 100644 --- a/client/src/main/java/com/vaadin/client/communication/ServerRpcQueue.java +++ b/client/src/main/java/com/vaadin/client/communication/ServerRpcQueue.java @@ -226,10 +226,11 @@ public class ServerRpcQueue { */ public boolean showLoadingIndicator() { for (MethodInvocation invocation : getAll()) { - if (isLegacyVariableChange(invocation)) { + if (isLegacyVariableChange(invocation) + || isJavascriptRpc(invocation)) { // Always show loading indicator for legacy requests return true; - } else if (!isJavascriptRpc(invocation)) { + } else { Type type = new Type(invocation.getInterfaceName(), null); Method method = type.getMethod(invocation.getMethodName()); if (!TypeDataStore.isNoLoadingIndicator(method)) { diff --git a/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java b/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java index 33f96e009c..9dd1a504ab 100644 --- a/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java +++ b/client/src/main/java/com/vaadin/client/data/AbstractRemoteDataSource.java @@ -378,7 +378,7 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> { } private void handleMissingRows(Range range) { - if (range.isEmpty()) { + if (range.isEmpty() || !canFetchData()) { return; } currentRequestCallback = new RequestRowsCallback<>(this, range); @@ -794,4 +794,17 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> { protected boolean isPinned(T row) { return pinnedRows.containsKey(getRowKey(row)); } + + /** + * Checks if it is possible to currently fetch data from the remote data + * source. + * + * @return <code>true</code> if it is ok to try to fetch data, + * <code>false</code> if it is known that fetching data will fail + * and should not be tried right now. + * @since 7.7.2 + */ + protected boolean canFetchData() { + return true; + } } diff --git a/client/src/main/java/com/vaadin/client/data/DataSource.java b/client/src/main/java/com/vaadin/client/data/DataSource.java index fdec4b9a38..4645957111 100644 --- a/client/src/main/java/com/vaadin/client/data/DataSource.java +++ b/client/src/main/java/com/vaadin/client/data/DataSource.java @@ -217,4 +217,14 @@ public interface DataSource<T> { * means that the row is not currently in this data source's cache. */ public RowHandle<T> getHandle(T row); + + /** + * Checks whether this data source is currently waiting for more rows to + * become available. + * + * @return <code>true</code> if waiting for data; otherwise + * <code>false</code> + * @since 7.7.2 + */ + public boolean isWaitingForData(); } diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java b/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java index 7e11c6c0d9..c62c5f032f 100644 --- a/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java +++ b/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java @@ -16,6 +16,8 @@ package com.vaadin.client.widget.escalator; +import com.google.gwt.animation.client.AnimationScheduler; +import com.google.gwt.animation.client.AnimationScheduler.AnimationSupportDetector; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; @@ -31,6 +33,7 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.Timer; +import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; import com.vaadin.client.WidgetUtil; import com.vaadin.client.widget.grid.events.ScrollEvent; @@ -47,6 +50,9 @@ import com.vaadin.client.widget.grid.events.ScrollHandler; */ public abstract class ScrollbarBundle implements DeferredWorker { + private static final boolean supportsRequestAnimationFrame = new AnimationSupportDetector() + .isNativelySupported(); + private class ScrollEventFirer { private final ScheduledCommand fireEventCommand = new ScheduledCommand() { @Override @@ -91,7 +97,17 @@ public abstract class ScrollbarBundle implements DeferredWorker { * We'll gather all the scroll events, and only fire once, once * everything has calmed down. */ - Scheduler.get().scheduleDeferred(fireEventCommand); + if (supportsRequestAnimationFrame) { + // Chrome MUST use this as deferred commands will sometimes + // be run with a 300+ ms delay when scrolling. + AnimationScheduler.get().requestAnimationFrame( + timestamp -> fireEventCommand.execute()); + } else { + // Does not support requestAnimationFrame and the fallback + // uses a delay of 16ms, we stick to the old deferred + // command which uses a delay of 0ms + Scheduler.get().scheduleDeferred(fireEventCommand); + } isBeingFired = true; } } @@ -449,13 +465,25 @@ public abstract class ScrollbarBundle implements DeferredWorker { * set either <code>overflow-x</code> or <code>overflow-y</code> to " * <code>scroll</code>" in the scrollbar's direction. * <p> - * This is an IE8 workaround, since it doesn't always show scrollbars with - * <code>overflow: auto</code> enabled. + * This method is an IE8 workaround, since it doesn't always show scrollbars + * with <code>overflow: auto</code> enabled. + * <p> + * Firefox on the other hand loses pending scroll events when the scrollbar + * is hidden, so the event must be fired manually. + * <p> + * When IE8 support is dropped, this should really be simplified. */ protected void forceScrollbar(boolean enable) { if (enable) { root.getStyle().clearDisplay(); } else { + if (BrowserInfo.get().isFirefox()) { + /* + * This is related to the Firefox workaround in setScrollSize + * for setScrollPos(0) + */ + scrollEventFirer.scheduleEvent(); + } root.getStyle().setDisplay(Display.NONE); } internalForceScrollbar(enable); @@ -603,21 +631,37 @@ public abstract class ScrollbarBundle implements DeferredWorker { * This needs to be made step-by-step because IE8 flat-out refuses to * fire a scroll event when the scroll size becomes smaller than the * offset size. All other browser need to suffer alongside. + * + * This really should be changed to not use any temporary scroll + * handlers at all once IE8 support is dropped, like now done only for + * Firefox. */ boolean newScrollSizeIsSmallerThanOffsetSize = px <= getOffsetSize(); boolean scrollSizeBecomesSmallerThanOffsetSize = showsScrollHandle() && newScrollSizeIsSmallerThanOffsetSize; if (scrollSizeBecomesSmallerThanOffsetSize && getScrollPos() != 0) { - // must be a field because Java insists. - scrollSizeTemporaryScrollHandler = addScrollHandler( - new ScrollHandler() { - @Override - public void onScroll(ScrollEvent event) { - setScrollSizeNow(px); - } - }); + /* + * For whatever reason, Firefox loses the scroll event in this case + * and the onscroll handler is never called (happens when reducing + * size from 1000 items to 1 while being scrolled a bit down, see + * #19802). Based on the comment above, only IE8 should really use + * 'delayedSizeSet' + */ + boolean delayedSizeSet = !BrowserInfo.get().isFirefox(); + if (delayedSizeSet) { + scrollSizeTemporaryScrollHandler = addScrollHandler( + new ScrollHandler() { + @Override + public void onScroll(ScrollEvent event) { + setScrollSizeNow(px); + } + }); + } setScrollPos(0); + if (!delayedSizeSet) { + setScrollSizeNow(px); + } } else { setScrollSizeNow(px); } @@ -863,7 +907,10 @@ public abstract class ScrollbarBundle implements DeferredWorker { @Override public boolean isWorkPending() { + // Need to include scrollEventFirer.isBeingFired as it might use + // requestAnimationFrame - which is not automatically checked return scrollSizeTemporaryScrollHandler != null - || offsetSizeTemporaryScrollHandler != null; + || offsetSizeTemporaryScrollHandler != null + || scrollEventFirer.isBeingFired; } } diff --git a/client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java b/client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java index 9767a230bb..355840d4ce 100644 --- a/client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java +++ b/client/src/main/java/com/vaadin/client/widget/grid/datasources/ListDataSource.java @@ -457,6 +457,11 @@ public class ListDataSource<T> implements DataSource<T> { }; } + @Override + public boolean isWaitingForData() { + return false; + } + private Stream<DataChangeHandler> getHandlers() { Set<DataChangeHandler> copy = new LinkedHashSet<>(changeHandlers); return copy.stream(); diff --git a/client/src/main/java/com/vaadin/client/widgets/Escalator.java b/client/src/main/java/com/vaadin/client/widgets/Escalator.java index 77afccdb30..fdd4c22645 100644 --- a/client/src/main/java/com/vaadin/client/widgets/Escalator.java +++ b/client/src/main/java/com/vaadin/client/widgets/Escalator.java @@ -672,13 +672,13 @@ public class Escalator extends Widget /*-{ var vScroll = esc.@com.vaadin.client.widgets.Escalator::verticalScrollbar; var vScrollElem = vScroll.@com.vaadin.client.widget.escalator.ScrollbarBundle::getElement()(); - + var hScroll = esc.@com.vaadin.client.widgets.Escalator::horizontalScrollbar; var hScrollElem = hScroll.@com.vaadin.client.widget.escalator.ScrollbarBundle::getElement()(); - + return $entry(function(e) { var target = e.target; - + // in case the scroll event was native (i.e. scrollbars were dragged, or // the scrollTop/Left was manually modified), the bundles have old cache // values. We need to make sure that the caches are kept up to date. @@ -699,29 +699,29 @@ public class Escalator extends Widget return $entry(function(e) { var deltaX = e.deltaX ? e.deltaX : -0.5*e.wheelDeltaX; var deltaY = e.deltaY ? e.deltaY : -0.5*e.wheelDeltaY; - + // Delta mode 0 is in pixels; we don't need to do anything... - + // A delta mode of 1 means we're scrolling by lines instead of pixels // We need to scale the number of lines by the default line height if(e.deltaMode === 1) { var brc = esc.@com.vaadin.client.widgets.Escalator::body; deltaY *= brc.@com.vaadin.client.widgets.Escalator.AbstractRowContainer::getDefaultRowHeight()(); } - + // Other delta modes aren't supported if((e.deltaMode !== undefined) && (e.deltaMode >= 2 || e.deltaMode < 0)) { var msg = "Unsupported wheel delta mode \"" + e.deltaMode + "\""; - + // Print warning message esc.@com.vaadin.client.widgets.Escalator::logWarning(*)(msg); } - + // IE8 has only delta y if (isNaN(deltaY)) { deltaY = -0.5*e.wheelDelta; } - + @com.vaadin.client.widgets.Escalator.JsniUtil::moveScrollFromEvent(*)(esc, deltaX, deltaY, e); }); }-*/; @@ -4170,6 +4170,11 @@ public class Escalator extends Widget frozenColumns += numberOfColumns; } + // Add to DOM + header.paintInsertColumns(index, numberOfColumns, frozen); + body.paintInsertColumns(index, numberOfColumns, frozen); + footer.paintInsertColumns(index, numberOfColumns, frozen); + // this needs to be before the scrollbar adjustment. boolean scrollbarWasNeeded = horizontalScrollbar .getOffsetSize() < horizontalScrollbar.getScrollSize(); @@ -4177,14 +4182,12 @@ public class Escalator extends Widget boolean scrollbarIsNowNeeded = horizontalScrollbar .getOffsetSize() < horizontalScrollbar.getScrollSize(); if (!scrollbarWasNeeded && scrollbarIsNowNeeded) { + // This might as a side effect move rows around (when scrolled + // all the way down) and require the DOM to be up to date, i.e. + // the column to be added body.verifyEscalatorCount(); } - // Add to DOM - header.paintInsertColumns(index, numberOfColumns, frozen); - body.paintInsertColumns(index, numberOfColumns, frozen); - footer.paintInsertColumns(index, numberOfColumns, frozen); - // fix initial width if (header.getRowCount() > 0 || body.getRowCount() > 0 || footer.getRowCount() > 0) { diff --git a/client/src/main/java/com/vaadin/client/widgets/Grid.java b/client/src/main/java/com/vaadin/client/widgets/Grid.java index 9a87d82363..eac958fdce 100644 --- a/client/src/main/java/com/vaadin/client/widgets/Grid.java +++ b/client/src/main/java/com/vaadin/client/widgets/Grid.java @@ -3163,7 +3163,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, rescheduleCount = 0; Scheduler.get().scheduleDeferred(this); } - } else if (dataIsBeingFetched) { + } else if (currentDataAvailable.isEmpty() + && dataSource.isWaitingForData()) { Scheduler.get().scheduleDeferred(this); } else { calculate(); @@ -3199,7 +3200,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, isScheduled = false; rescheduleCount = 0; - assert !dataIsBeingFetched : "Trying to calculate column widths even though data is still being fetched."; + assert !(currentDataAvailable.isEmpty() && dataSource + .isWaitingForData()) : "Trying to calculate column widths without data while data is still being fetched."; if (columnsAreGuaranteedToBeWiderThanGrid()) { applyColumnWidths(); @@ -4060,21 +4062,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private final Editor<T> editor = GWT.create(Editor.class); - private boolean dataIsBeingFetched = false; - /** * The cell a click event originated from * <p> * This is a workaround to make Chrome work like Firefox. In Chrome, * normally if you start a drag on one cell and release on: * <ul> - * <li>that same cell, the click event is that {@code - * - <td>}. - * <li>a cell on that same row, the click event is the parent {@code - * - <tr> - * }. + * <li>that same cell, the click event is that <code><td></code>. + * <li>a cell on that same row, the click event is the parent + * <code><tr></code>. * <li>a cell on another row, the click event is the table section ancestor * ({@code <thead>}, {@code <tbody>} or {@code <tfoot>}). * </ul> @@ -5672,7 +5668,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, initialWidth = col.getWidthActual(); minCellWidth = escalator.getMinCellWidth( - getColumns().indexOf(col)); + getVisibleColumns().indexOf(col)); for (Column<?, T> c : getVisibleColumns()) { if (selectionColumn == c) { // Don't modify selection column. @@ -5681,8 +5677,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (c.getWidth() < 0) { c.setWidth(c.getWidthActual()); - fireEvent(new ColumnResizeEvent<>( - c)); + fireEvent( + new ColumnResizeEvent<>(c)); } } @@ -5907,7 +5903,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public void onRowVisibilityChange( RowVisibilityChangeEvent event) { if (dataSource != null && dataSource.size() != 0) { - dataIsBeingFetched = true; dataSource.ensureAvailability( event.getFirstVisibleRow(), event.getVisibleRowCount()); @@ -5947,12 +5942,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } }); - addDataAvailableHandler(new DataAvailableHandler() { - @Override - public void onDataAvailable(DataAvailableEvent event) { - dataIsBeingFetched = false; - } - }); } @Override @@ -6291,8 +6280,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return A unmodifiable list of the columns in the grid */ public List<Column<?, T>> getColumns() { - return Collections - .unmodifiableList(new ArrayList<>(columns)); + return Collections.unmodifiableList(new ArrayList<>(columns)); } /** @@ -6717,8 +6705,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, int oldSize = body.getRowCount(); // Hide all details. - Set<Integer> oldDetails = new HashSet<>( - visibleDetails); + Set<Integer> oldDetails = new HashSet<>(visibleDetails); for (int i : oldDetails) { setDetailsVisible(i, false); } @@ -6734,7 +6721,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } if (newSize > 0) { - dataIsBeingFetched = true; Range visibleRowRange = escalator .getVisibleRowRange(); dataSource.ensureAvailability( @@ -7829,7 +7815,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { - if (!dataIsBeingFetched) { + if (!dataSource.isWaitingForData()) { handler.onDataAvailable( new DataAvailableEvent(currentDataAvailable)); } @@ -8108,8 +8094,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ private void sort(boolean userOriginated) { refreshHeader(); - fireEvent(new SortEvent<>(this, - Collections.unmodifiableList(sortOrder), userOriginated)); + fireEvent(new SortEvent<>(this, Collections.unmodifiableList(sortOrder), + userOriginated)); } private int getLastVisibleRowIndex() { @@ -8150,7 +8136,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, @Override public boolean isWorkPending() { - return escalator.isWorkPending() || dataIsBeingFetched + return escalator.isWorkPending() || dataSource.isWaitingForData() || autoColumnWidthsRecalculator.isScheduled() || editor.isWorkPending(); } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java index 363d3c047d..f800300440 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/connectors/RpcDataSourceConnector.java @@ -73,7 +73,7 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector { registerRpc(DataProviderRpc.class, new DataProviderRpc() { @Override public void setRowData(int firstRow, JsonArray rowArray) { - ArrayList<JsonObject> rows = new ArrayList<JsonObject>( + ArrayList<JsonObject> rows = new ArrayList<>( rowArray.length()); for (int i = 0; i < rowArray.length(); i++) { JsonObject rowObject = rowArray.getObject(i); @@ -240,6 +240,11 @@ public class RpcDataSourceConnector extends AbstractExtensionConnector { droppedRowKeys.set(droppedRowKeys.length(), getRowKey(row)); } } + + @Override + protected boolean canFetchData() { + return isEnabled(); + } } private final RpcDataSource dataSource = new RpcDataSource(); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java index bdd4240818..20b1e5d1b9 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/escalator/ScrollbarBundle.java @@ -16,6 +16,8 @@ package com.vaadin.v7.client.widget.escalator; +import com.google.gwt.animation.client.AnimationScheduler; +import com.google.gwt.animation.client.AnimationScheduler.AnimationSupportDetector; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; @@ -31,6 +33,7 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.Timer; +import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; import com.vaadin.client.WidgetUtil; import com.vaadin.v7.client.widget.grid.events.ScrollEvent; @@ -47,6 +50,9 @@ import com.vaadin.v7.client.widget.grid.events.ScrollHandler; */ public abstract class ScrollbarBundle implements DeferredWorker { + private static final boolean supportsRequestAnimationFrame = new AnimationSupportDetector() + .isNativelySupported(); + private class ScrollEventFirer { private final ScheduledCommand fireEventCommand = new ScheduledCommand() { @Override @@ -91,7 +97,17 @@ public abstract class ScrollbarBundle implements DeferredWorker { * We'll gather all the scroll events, and only fire once, once * everything has calmed down. */ - Scheduler.get().scheduleDeferred(fireEventCommand); + if (supportsRequestAnimationFrame) { + // Chrome MUST use this as deferred commands will sometimes + // be run with a 300+ ms delay when scrolling. + AnimationScheduler.get().requestAnimationFrame( + timestamp -> fireEventCommand.execute()); + } else { + // Does not support requestAnimationFrame and the fallback + // uses a delay of 16ms, we stick to the old deferred + // command which uses a delay of 0ms + Scheduler.get().scheduleDeferred(fireEventCommand); + } isBeingFired = true; } } @@ -449,13 +465,25 @@ public abstract class ScrollbarBundle implements DeferredWorker { * set either <code>overflow-x</code> or <code>overflow-y</code> to " * <code>scroll</code>" in the scrollbar's direction. * <p> - * This is an IE8 workaround, since it doesn't always show scrollbars with - * <code>overflow: auto</code> enabled. + * This method is an IE8 workaround, since it doesn't always show scrollbars + * with <code>overflow: auto</code> enabled. + * <p> + * Firefox on the other hand loses pending scroll events when the scrollbar + * is hidden, so the event must be fired manually. + * <p> + * When IE8 support is dropped, this should really be simplified. */ protected void forceScrollbar(boolean enable) { if (enable) { root.getStyle().clearDisplay(); } else { + if (BrowserInfo.get().isFirefox()) { + /* + * This is related to the Firefox workaround in setScrollSize + * for setScrollPos(0) + */ + scrollEventFirer.scheduleEvent(); + } root.getStyle().setDisplay(Display.NONE); } internalForceScrollbar(enable); @@ -603,21 +631,37 @@ public abstract class ScrollbarBundle implements DeferredWorker { * This needs to be made step-by-step because IE8 flat-out refuses to * fire a scroll event when the scroll size becomes smaller than the * offset size. All other browser need to suffer alongside. + * + * This really should be changed to not use any temporary scroll + * handlers at all once IE8 support is dropped, like now done only for + * Firefox. */ boolean newScrollSizeIsSmallerThanOffsetSize = px <= getOffsetSize(); boolean scrollSizeBecomesSmallerThanOffsetSize = showsScrollHandle() && newScrollSizeIsSmallerThanOffsetSize; if (scrollSizeBecomesSmallerThanOffsetSize && getScrollPos() != 0) { - // must be a field because Java insists. - scrollSizeTemporaryScrollHandler = addScrollHandler( - new ScrollHandler() { - @Override - public void onScroll(ScrollEvent event) { - setScrollSizeNow(px); - } - }); + /* + * For whatever reason, Firefox loses the scroll event in this case + * and the onscroll handler is never called (happens when reducing + * size from 1000 items to 1 while being scrolled a bit down, see + * #19802). Based on the comment above, only IE8 should really use + * 'delayedSizeSet' + */ + boolean delayedSizeSet = !BrowserInfo.get().isFirefox(); + if (delayedSizeSet) { + scrollSizeTemporaryScrollHandler = addScrollHandler( + new ScrollHandler() { + @Override + public void onScroll(ScrollEvent event) { + setScrollSizeNow(px); + } + }); + } setScrollPos(0); + if (!delayedSizeSet) { + setScrollSizeNow(px); + } } else { setScrollSizeNow(px); } @@ -863,7 +907,10 @@ public abstract class ScrollbarBundle implements DeferredWorker { @Override public boolean isWorkPending() { + // Need to include scrollEventFirer.isBeingFired as it might use + // requestAnimationFrame - which is not automatically checked return scrollSizeTemporaryScrollHandler != null - || offsetSizeTemporaryScrollHandler != null; + || offsetSizeTemporaryScrollHandler != null + || scrollEventFirer.isBeingFired; } } diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/datasources/ListDataSource.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/datasources/ListDataSource.java index 994e8059eb..d80cdad3c9 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/datasources/ListDataSource.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widget/grid/datasources/ListDataSource.java @@ -344,7 +344,7 @@ public class ListDataSource<T> implements DataSource<T> { if (datasource == null) { throw new IllegalArgumentException("datasource cannot be null"); } - ds = new ArrayList<T>(datasource); + ds = new ArrayList<>(datasource); wrapper = new ListWrapper(); } @@ -358,9 +358,9 @@ public class ListDataSource<T> implements DataSource<T> { */ public ListDataSource(T... rows) { if (rows == null) { - ds = new ArrayList<T>(); + ds = new ArrayList<>(); } else { - ds = new ArrayList<T>(Arrays.asList(rows)); + ds = new ArrayList<>(Arrays.asList(rows)); } wrapper = new ListWrapper(); } @@ -457,6 +457,11 @@ public class ListDataSource<T> implements DataSource<T> { }; } + @Override + public boolean isWaitingForData() { + return false; + } + private Stream<DataChangeHandler> getHandlers() { Set<DataChangeHandler> copy = new LinkedHashSet<>(changeHandlers); return copy.stream(); diff --git a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java index e79237702b..afc9cd8a45 100644 --- a/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java +++ b/compatibility-client/src/main/java/com/vaadin/v7/client/widgets/Grid.java @@ -442,14 +442,14 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ public abstract static class StaticRow<CELLTYPE extends StaticCell> { - private Map<Column<?, ?>, CELLTYPE> cells = new HashMap<Column<?, ?>, CELLTYPE>(); + private Map<Column<?, ?>, CELLTYPE> cells = new HashMap<>(); private StaticSection<?> section; /** * Map from set of spanned columns to cell meta data. */ - private Map<Set<Column<?, ?>>, CELLTYPE> cellGroups = new HashMap<Set<Column<?, ?>>, CELLTYPE>(); + private Map<Set<Column<?, ?>>, CELLTYPE> cellGroups = new HashMap<>(); /** * A custom style name for the row or null if none is set. @@ -497,7 +497,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, "You can't merge less than 2 columns together."); } - HashSet<Column<?, ?>> columnGroup = new HashSet<Column<?, ?>>(); + HashSet<Column<?, ?>> columnGroup = new HashSet<>(); // NOTE: this doesn't care about hidden columns, those are // filtered in calculateColspans() for (Column<?, ?> column : columns) { @@ -591,7 +591,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private boolean checkMergedCellIsContinuous( Set<Column<?, ?>> mergedCell) { // no matter if hidden or not, just check for continuous order - final List<Column<?, ?>> columnOrder = new ArrayList<Column<?, ?>>( + final List<Column<?, ?>> columnOrder = new ArrayList<>( section.grid.getColumns()); if (!columnOrder.containsAll(mergedCell)) { @@ -661,7 +661,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ void detach() { // Avoid calling detach twice for a merged cell - HashSet<CELLTYPE> cells = new HashSet<CELLTYPE>(); + HashSet<CELLTYPE> cells = new HashSet<>(); for (Column<?, ?> column : getSection().grid.getColumns()) { cells.add(getCell(column)); } @@ -673,7 +673,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Grid<?> grid; - private List<ROWTYPE> rows = new ArrayList<ROWTYPE>(); + private List<ROWTYPE> rows = new ArrayList<>(); private boolean visible = true; @@ -1337,8 +1337,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Should only be added to the DOM when there's a message to show private DivElement message = DivElement.as(DOM.createDiv()); - private Map<Column<?, T>, Widget> columnToWidget = new HashMap<Column<?, T>, Widget>(); - private List<HandlerRegistration> focusHandlers = new ArrayList<HandlerRegistration>(); + private Map<Column<?, T>, Widget> columnToWidget = new HashMap<>(); + private List<HandlerRegistration> focusHandlers = new ArrayList<>(); private boolean enabled = false; private State state = State.INACTIVE; @@ -1433,7 +1433,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, }; /** A set of all the columns that display an error flag. */ - private final Set<Column<?, T>> columnErrors = new HashSet<Grid.Column<?, T>>(); + private final Set<Column<?, T>> columnErrors = new HashSet<>(); private boolean buffered = true; /** Original position of editor */ @@ -1629,7 +1629,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, throw new IllegalStateException( "Cannot cancel edit: editor is not in edit mode"); } - handler.cancel(new EditorRequestImpl<T>(grid, rowIndex, + handler.cancel(new EditorRequestImpl<>(grid, rowIndex, focusedColumnIndex, null)); doCancel(); } @@ -1675,7 +1675,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, state = State.SAVING; setButtonsEnabled(false); saveTimeout.schedule(SAVE_TIMEOUT_MS); - EditorRequest<T> request = new EditorRequestImpl<T>(grid, rowIndex, + EditorRequest<T> request = new EditorRequestImpl<>(grid, rowIndex, focusedColumnIndex, saveRequestCallback); handler.save(request); updateSelectionCheckboxesAsNeeded(true); @@ -1739,7 +1739,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (state == State.ACTIVATING) { state = State.BINDING; bindTimeout.schedule(BIND_TIMEOUT_MS); - EditorRequest<T> request = new EditorRequestImpl<T>(grid, + EditorRequest<T> request = new EditorRequestImpl<>(grid, rowIndex, columnIndex, bindRequestCallback); handler.bind(request); grid.getEscalator().setScrollLocked(Direction.VERTICAL, @@ -2270,7 +2270,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, extends KeyEvent<HANDLER> { private Grid<?> grid; - private final Type<HANDLER> associatedType = new Type<HANDLER>( + private final Type<HANDLER> associatedType = new Type<>( getBrowserEventType(), this); private final CellReference<?> targetCell; @@ -2330,7 +2330,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Grid<?> grid; private final CellReference<?> targetCell; - private final Type<HANDLER> associatedType = new Type<HANDLER>( + private final Type<HANDLER> associatedType = new Type<>( getBrowserEventType(), this); public AbstractGridMouseEvent(Grid<?> grid, @@ -2408,7 +2408,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ private static final double DETAILS_ROW_INITIAL_HEIGHT = 50; - private EventCellReference<T> eventCell = new EventCellReference<T>(this); + private EventCellReference<T> eventCell = new EventCellReference<>(this); private GridKeyDownEvent keyDown = new GridKeyDownEvent(this, eventCell); private GridKeyUpEvent keyUp = new GridKeyUpEvent(this, eventCell); private GridKeyPressEvent keyPress = new GridKeyPressEvent(this, eventCell); @@ -2882,7 +2882,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public void onValueChange( ValueChangeEvent<Boolean> event) { if (event.getValue()) { - fireEvent(new SelectAllEvent<T>(model)); + fireEvent(new SelectAllEvent<>(model)); selected = true; } else { model.deselectAll(); @@ -3167,7 +3167,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, rescheduleCount = 0; Scheduler.get().scheduleDeferred(this); } - } else if (dataIsBeingFetched) { + } else if (currentDataAvailable.isEmpty() + && dataSource.isWaitingForData()) { Scheduler.get().scheduleDeferred(this); } else { calculate(); @@ -3203,7 +3204,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, isScheduled = false; rescheduleCount = 0; - assert !dataIsBeingFetched : "Trying to calculate column widths even though data is still being fetched."; + assert !(currentDataAvailable.isEmpty() && dataSource + .isWaitingForData()) : "Trying to calculate column widths without data while data is still being fetched."; if (columnsAreGuaranteedToBeWiderThanGrid()) { applyColumnWidths(); @@ -3232,7 +3234,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, /* Step 1: Apply all column widths as they are. */ - Map<Integer, Double> selfWidths = new LinkedHashMap<Integer, Double>(); + Map<Integer, Double> selfWidths = new LinkedHashMap<>(); List<Column<?, T>> columns = getVisibleColumns(); for (int index = 0; index < columns.size(); index++) { selfWidths.put(index, columns.get(index).getWidth()); @@ -3246,7 +3248,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * violated, fix it. */ - Map<Integer, Double> constrainedWidths = new LinkedHashMap<Integer, Double>(); + Map<Integer, Double> constrainedWidths = new LinkedHashMap<>(); for (int index = 0; index < columns.size(); index++) { Column<?, T> column = columns.get(index); @@ -3271,9 +3273,9 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, boolean defaultExpandRatios = true; int totalRatios = 0; double reservedPixels = 0; - final Set<Column<?, T>> columnsToExpand = new HashSet<Column<?, T>>(); - List<Column<?, T>> nonFixedColumns = new ArrayList<Column<?, T>>(); - Map<Integer, Double> columnSizes = new HashMap<Integer, Double>(); + final Set<Column<?, T>> columnsToExpand = new HashSet<>(); + List<Column<?, T>> nonFixedColumns = new ArrayList<>(); + Map<Integer, Double> columnSizes = new HashMap<>(); final List<Column<?, T>> visibleColumns = getVisibleColumns(); /* @@ -3536,7 +3538,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private static final String STRIPE_CLASSNAME = "stripe"; - private final Map<Element, Widget> elementToWidgetMap = new HashMap<Element, Widget>(); + private final Map<Element, Widget> elementToWidgetMap = new HashMap<>(); @Override public void init(Spacer spacer) { @@ -3918,7 +3920,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private final class ColumnHider { /** Map from columns to their hiding toggles, component might change */ - private HashMap<Column<?, T>, MenuItem> columnToHidingToggleMap = new HashMap<Grid.Column<?, T>, MenuItem>(); + private HashMap<Column<?, T>, MenuItem> columnToHidingToggleMap = new HashMap<>(); /** * When column is being hidden with a toggle, do not refresh toggles for @@ -4017,7 +4019,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, /** * List of columns in the grid. Order defines the visible order. */ - private List<Column<?, T>> columns = new ArrayList<Column<?, T>>(); + private List<Column<?, T>> columns = new ArrayList<>(); /** * The datasource currently in use. <em>Note:</em> it is <code>null</code> @@ -4041,7 +4043,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * Current sort order. The (private) sort() method reads this list to * determine the order in which to present rows. */ - private List<SortOrder> sortOrder = new ArrayList<SortOrder>(); + private List<SortOrder> sortOrder = new ArrayList<>(); private Renderer<Boolean> selectColumnRenderer = null; @@ -4064,21 +4066,15 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private final Editor<T> editor = GWT.create(Editor.class); - private boolean dataIsBeingFetched = false; - /** * The cell a click event originated from * <p> * This is a workaround to make Chrome work like Firefox. In Chrome, * normally if you start a drag on one cell and release on: * <ul> - * <li>that same cell, the click event is that {@code - * - <td>}. - * <li>a cell on that same row, the click event is the parent {@code - * - <tr> - * }. + * <li>that same cell, the click event is that <code><td></code>. + * <li>a cell on that same row, the click event is the parent + * <code><tr></code>. * <li>a cell on another row, the click event is the table section ancestor * ({@code <thead>}, {@code <tbody>} or {@code <tfoot>}). * </ul> @@ -4099,7 +4095,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private DetailsGenerator detailsGenerator = DetailsGenerator.NULL; private GridSpacerUpdater gridSpacerUpdater = new GridSpacerUpdater(); /** A set keeping track of the indices of all currently open details */ - private Set<Integer> visibleDetails = new HashSet<Integer>(); + private Set<Integer> visibleDetails = new HashSet<>(); private boolean columnReorderingAllowed; @@ -4149,7 +4145,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * Map of possible drop positions for the column and the corresponding * column index. */ - private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<Double, Integer>(); + private final TreeMap<Double, Integer> possibleDropPositions = new TreeMap<>(); /** * Makes sure that drag cancel doesn't cause anything unwanted like sort */ @@ -4348,7 +4344,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, && latestColumnDropIndex != (draggedColumnIndex + colspan)) { List<Column<?, T>> columns = getColumns(); - List<Column<?, T>> reordered = new ArrayList<Column<?, T>>(); + List<Column<?, T>> reordered = new ArrayList<>(); if (draggedColumnIndex < latestColumnDropIndex) { reordered.addAll(columns.subList(0, draggedColumnIndex)); reordered.addAll( @@ -4476,8 +4472,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, int leftBound = -1; int rightBound = getColumnCount() + 1; - final HashSet<Integer> unavailableColumnDropIndices = new HashSet<Integer>(); - final List<StaticRow<?>> rows = new ArrayList<StaticRow<?>>(); + final HashSet<Integer> unavailableColumnDropIndices = new HashSet<>(); + final List<StaticRow<?>> rows = new ArrayList<>(); rows.addAll(header.getRows()); rows.addAll(footer.getRows()); for (StaticRow<?> row : rows) { @@ -5063,7 +5059,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, grid.header.updateColSpans(); grid.footer.updateColSpans(); scheduleColumnWidthRecalculator(); - this.grid.fireEvent(new ColumnVisibilityChangeEvent<T>(this, + this.grid.fireEvent(new ColumnVisibilityChangeEvent<>(this, hidden, userOriginated)); } } @@ -5717,7 +5713,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, initialWidth = col.getWidthActual(); minCellWidth = escalator.getMinCellWidth( - getColumns().indexOf(col)); + getVisibleColumns().indexOf(col)); for (Column<?, T> c : getVisibleColumns()) { if (selectionColumn == c) { // Don't modify selection column. @@ -5726,8 +5722,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (c.getWidth() < 0) { c.setWidth(c.getWidthActual()); - fireEvent(new ColumnResizeEvent<T>( - c)); + fireEvent( + new ColumnResizeEvent<>(c)); } } @@ -5737,7 +5733,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, @Override public void onComplete() { - fireEvent(new ColumnResizeEvent<T>(col)); + fireEvent(new ColumnResizeEvent<>(col)); WidgetUtil.setTextSelectionEnabled( getElement(), true); @@ -5819,7 +5815,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, escalator.getColumnConfiguration().setColumnWidth(colIndex, minWidth); - fireEvent(new ColumnResizeEvent<T>(column)); + fireEvent(new ColumnResizeEvent<>(column)); } } @@ -5937,7 +5933,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, public void onRowVisibilityChange( RowVisibilityChangeEvent event) { if (dataSource != null && dataSource.size() != 0) { - dataIsBeingFetched = true; dataSource.ensureAvailability( event.getFirstVisibleRow(), event.getVisibleRowCount()); @@ -5977,12 +5972,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } }); - addDataAvailableHandler(new DataAvailableHandler() { - @Override - public void onDataAvailable(DataAvailableEvent event) { - dataIsBeingFetched = false; - } - }); } @Override @@ -6229,7 +6218,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, column.reapplyWidth(); // Sink all renderer events - Set<String> events = new HashSet<String>(); + Set<String> events = new HashSet<>(); events.addAll(getConsumedEventsForRenderer(column.getRenderer())); if (column.isHidable()) { @@ -6321,8 +6310,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return A unmodifiable list of the columns in the grid */ public List<Column<?, T>> getColumns() { - return Collections - .unmodifiableList(new ArrayList<Column<?, T>>(columns)); + return Collections.unmodifiableList(new ArrayList<>(columns)); } /** @@ -6334,7 +6322,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, * @return A unmodifiable list of the currently visible columns in the grid */ public List<Column<?, T>> getVisibleColumns() { - ArrayList<Column<?, T>> visible = new ArrayList<Column<?, T>>(); + ArrayList<Column<?, T>> visible = new ArrayList<>(); for (Column<?, T> c : columns) { if (!c.isHidden()) { visible.add(c); @@ -6749,8 +6737,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, int oldSize = body.getRowCount(); // Hide all details. - Set<Integer> oldDetails = new HashSet<Integer>( - visibleDetails); + Set<Integer> oldDetails = new HashSet<>(visibleDetails); for (int i : oldDetails) { setDetailsVisible(i, false); } @@ -6766,7 +6753,6 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } if (newSize > 0) { - dataIsBeingFetched = true; Range visibleRowRange = escalator .getVisibleRowRange(); dataSource.ensureAvailability( @@ -7123,7 +7109,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, } private Set<String> getConsumedEventsForRenderer(Renderer<?> renderer) { - Set<String> events = new HashSet<String>(); + Set<String> events = new HashSet<>(); if (renderer instanceof ComplexRenderer) { Collection<String> consumedEvents = ((ComplexRenderer<?>) renderer) .getConsumedEvents(); @@ -7295,7 +7281,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, w = editor.getWidget(getColumn(editor.focusedColumnIndex)); } - EditorDomEvent<T> editorEvent = new EditorDomEvent<T>(event, + EditorDomEvent<T> editorEvent = new EditorDomEvent<>(event, getEventCell(), w); return getEditor().getEventHandler().handleEvent(editorEvent); @@ -7366,8 +7352,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, private Point rowEventTouchStartingPoint; private CellStyleGenerator<T> cellStyleGenerator; private RowStyleGenerator<T> rowStyleGenerator; - private RowReference<T> rowReference = new RowReference<T>(this); - private CellReference<T> cellReference = new CellReference<T>(rowReference); + private RowReference<T> rowReference = new RowReference<>(this); + private CellReference<T> cellReference = new CellReference<>(rowReference); private RendererCellReference rendererCellReference = new RendererCellReference( (RowReference<Object>) rowReference); @@ -7909,7 +7895,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { - if (!dataIsBeingFetched) { + if (!dataSource.isWaitingForData()) { handler.onDataAvailable( new DataAvailableEvent(currentDataAvailable)); } @@ -8188,8 +8174,8 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, */ private void sort(boolean userOriginated) { refreshHeader(); - fireEvent(new SortEvent<T>(this, - Collections.unmodifiableList(sortOrder), userOriginated)); + fireEvent(new SortEvent<>(this, Collections.unmodifiableList(sortOrder), + userOriginated)); } private int getLastVisibleRowIndex() { @@ -8230,7 +8216,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, @Override public boolean isWorkPending() { - return escalator.isWorkPending() || dataIsBeingFetched + return escalator.isWorkPending() || dataSource.isWaitingForData() || autoColumnWidthsRecalculator.isScheduled() || editor.isWorkPending(); } @@ -8270,7 +8256,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, // Trigger ComplexRenderer.destroy for old content conf.removeColumns(0, conf.getColumnCount()); - List<Column<?, T>> newOrder = new ArrayList<Column<?, T>>(); + List<Column<?, T>> newOrder = new ArrayList<>(); if (selectionColumn != null) { newOrder.add(selectionColumn); } @@ -8548,7 +8534,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, @Override protected void onDetach() { - Set<Integer> details = new HashSet<Integer>(visibleDetails); + Set<Integer> details = new HashSet<>(visibleDetails); for (int row : details) { setDetailsVisible(row, false); } @@ -8958,7 +8944,7 @@ public class Grid<T> extends ResizeComposite implements HasSelectionHandlers<T>, if (container != null) { Cell cell = container.getCell(element); if (cell != null) { - EventCellReference<T> cellRef = new EventCellReference<T>(this); + EventCellReference<T> cellRef = new EventCellReference<>(this); cellRef.set(cell, getSectionFromContainer(container)); return cellRef; } diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java index befdc26998..0be6b236d0 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/DateField.java @@ -635,6 +635,25 @@ public class DateField extends AbstractField<Date> implements } } + @Override + public void discard() { + Property prop = getPropertyDataSource(); + if (prop != null) { + Object value = prop.getValue(); + if (!isValid() && value == null) { + // If the user entered an invalid value in the date field + // getInternalValue() returns null. + // If the datasource also contains null, then + // updateValueFromDataSource() will then not clear the internal + // state + // and error indicators (ticket #8069). + setInternalValue(null); + } else { + super.discard(); + } + } + } + /* * only fires the event if preventValueChangeEvent flag is false */ diff --git a/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java b/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java index f89cf5544b..f7bcd8075f 100644 --- a/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java +++ b/compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java @@ -4560,6 +4560,11 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, private Object editedItemId = null; private boolean editorActive = false; + /** + * True while the editor is storing the field values, i.e. commiting the + * field group. + */ + private boolean editorSaving = false; private FieldGroup editorFieldGroup = new CustomFieldGroup(); private CellStyleGenerator cellStyleGenerator; @@ -6902,7 +6907,12 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, * @see FieldGroup#commit() */ public void saveEditor() throws CommitException { - editorFieldGroup.commit(); + try { + editorSaving = true; + editorFieldGroup.commit(); + } finally { + editorSaving = false; + } } /** @@ -6910,6 +6920,12 @@ public class Grid extends AbstractFocusable implements SelectionNotifier, * possible unsaved changes in the editor fields. */ public void cancelEditor() { + if (editorSaving) { + // If the editor is already saving the values, it's too late to + // cancel it. This prevents item set changes from propagating during + // save, causing discard to be run during commit. + return; + } if (isEditorActive()) { getEditorRpc() .cancel(getContainerDataSource().indexOfId(editedItemId)); diff --git a/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/ItemSetChangeDuringEditorCommit.java b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/ItemSetChangeDuringEditorCommit.java new file mode 100644 index 0000000000..0a97a84999 --- /dev/null +++ b/compatibility-server/src/test/java/com/vaadin/v7/tests/server/component/grid/ItemSetChangeDuringEditorCommit.java @@ -0,0 +1,106 @@ +package com.vaadin.v7.tests.server.component.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.server.ServerRpcManager.RpcInvocationException; +import com.vaadin.server.ServerRpcMethodInvocation; +import com.vaadin.tests.util.MockUI; +import com.vaadin.ui.UI; +import com.vaadin.v7.data.fieldgroup.FieldGroup; +import com.vaadin.v7.data.fieldgroup.FieldGroup.CommitException; +import com.vaadin.v7.data.util.IndexedContainer; +import com.vaadin.v7.shared.ui.grid.EditorServerRpc; +import com.vaadin.v7.ui.Grid; +import com.vaadin.v7.ui.TextField; + +public class ItemSetChangeDuringEditorCommit { + + private static class IndexedContainerImpl extends IndexedContainer { + + public IndexedContainerImpl() { + } + + @Override + public void fireItemSetChange() { + super.fireItemSetChange(); + } + } + + @Test + public void itemSetChangeDoesNotInterruptCommit() + throws RpcInvocationException, CommitException { + UI ui = new MockUI(); + final IndexedContainerImpl indexedContainer = new IndexedContainerImpl(); + indexedContainer.addContainerProperty("firstName", String.class, + "first"); + indexedContainer.addContainerProperty("lastName", String.class, "last"); + indexedContainer.addItem(); + indexedContainer.addItem(); + + Grid grid = new Grid(); + ui.setContent(grid); + grid.setContainerDataSource(indexedContainer); + grid.setEditorEnabled(true); + grid.getEditorFieldGroup() + .addCommitHandler(new FieldGroup.CommitHandler() { + @Override + public void preCommit(FieldGroup.CommitEvent commitEvent) + throws FieldGroup.CommitException { + } + + @Override + public void postCommit(FieldGroup.CommitEvent commitEvent) + throws FieldGroup.CommitException { + indexedContainer.fireItemSetChange(); + } + }); + + editItem(grid, 0); + ((TextField) grid.getEditorFieldGroup().getField("firstName")) + .setValue("New first"); + ((TextField) grid.getEditorFieldGroup().getField("lastName")) + .setValue("New last"); + grid.saveEditor(); + + Assert.assertEquals("New first", indexedContainer + .getContainerProperty(grid.getEditedItemId(), "firstName") + .getValue()); + Assert.assertEquals("New last", indexedContainer + .getContainerProperty(grid.getEditedItemId(), "lastName") + .getValue()); + + grid.cancelEditor(); + Assert.assertFalse(grid.isEditorActive()); + + editItem(grid, 0); + Assert.assertEquals("New first", + ((TextField) grid.getEditorFieldGroup().getField("firstName")) + .getValue()); + Assert.assertEquals("New last", + ((TextField) grid.getEditorFieldGroup().getField("lastName")) + .getValue()); + saveEditor(grid, 0); + } + + private void editItem(Grid grid, int itemIndex) + throws RpcInvocationException { + ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation( + grid.getConnectorId(), EditorServerRpc.class, "bind", 1); + invocation.setParameters(new Object[] { itemIndex }); + grid.getRpcManager(EditorServerRpc.class.getName()) + .applyInvocation(invocation); + Assert.assertTrue(grid.isEditorActive()); + + } + + private void saveEditor(Grid grid, int itemIndex) + throws RpcInvocationException { + ServerRpcMethodInvocation invocation = new ServerRpcMethodInvocation( + grid.getConnectorId(), EditorServerRpc.class, "save", 1); + invocation.setParameters(new Object[] { itemIndex }); + grid.getRpcManager(EditorServerRpc.class.getName()) + .applyInvocation(invocation); + + } +}
\ No newline at end of file @@ -13,13 +13,14 @@ <version>8.0-SNAPSHOT</version> <prerequisites> - <maven>3.0.5</maven> + <maven>3.1.0</maven> </prerequisites> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <!-- Used version numbers for dependencies --> <liferay.portal.version>6.0.2</liferay.portal.version> @@ -43,6 +44,9 @@ <!-- Dependency unpack directory --> <dependency.unpack.directory>${project.build.directory}/dependency-unpack</dependency.unpack.directory> + + <jetty.version>9.3.7.v20160115</jetty.version> + <phantomjs.version>2.1.1</phantomjs.version> </properties> <!-- TODO: remove this after maven plugin has been released --> @@ -135,6 +139,14 @@ <groupId>com.vaadin</groupId> <artifactId>vaadin-sass-compiler</artifactId> <version>${vaadin.sass.version}</version> + <exclusions> + <!-- No need to have the minifier included for development + mode on-the-fly compilation --> + <exclusion> + <groupId>com.yahoo.platform.yui</groupId> + <artifactId>yuicompressor</artifactId> + </exclusion> + </exclusions> </dependency> <dependency> <groupId>com.carrotsearch</groupId> @@ -340,6 +352,15 @@ <version>2.19.1</version> </plugin> <plugin> + <artifactId>maven-failsafe-plugin</artifactId> + <version>2.19.1</version> + </plugin> + <plugin> + <groupId>com.github.klieber</groupId> + <artifactId>phantomjs-maven-plugin</artifactId> + <version>0.7</version> + </plugin> + <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> </plugin> @@ -436,6 +457,25 @@ <ignore></ignore> </action> </pluginExecution> + <pluginExecution> + <pluginExecutionFilter> + <groupId> + com.github.klieber + </groupId> + <artifactId> + phantomjs-maven-plugin + </artifactId> + <versionRange> + [0.7,) + </versionRange> + <goals> + <goal>install</goal> + </goals> + </pluginExecutionFilter> + <action> + <ignore></ignore> + </action> + </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> @@ -503,6 +543,12 @@ <profiles> <profile> + <id>slowtest</id> + <modules> + <module>test</module> + </modules> + </profile> + <profile> <id>release</id> <activation> <activeByDefault>false</activeByDefault> diff --git a/scripts/BuildDemos.py b/scripts/BuildDemos.py index 4e4362b1df..7870e743de 100644 --- a/scripts/BuildDemos.py +++ b/scripts/BuildDemos.py @@ -18,6 +18,7 @@ from xml.etree.ElementTree import ElementTree demos = { "dashboard" : "https://github.com/vaadin/dashboard-demo.git", "addressbook" : "https://github.com/vaadin/addressbook.git", + "framework8-demo" : "https://github.com/vaadin/framework8-demo", "sampler" : "demos/sampler" # "my-demo" : ("my_demo_url_or_path", "my-demo-dev-branch") } diff --git a/scripts/BuildHelpers.py b/scripts/BuildHelpers.py index 8f6e2dee60..8a9baee6a0 100644 --- a/scripts/BuildHelpers.py +++ b/scripts/BuildHelpers.py @@ -77,6 +77,8 @@ def mavenValidate(artifactId, mvnCmd = mavenCmd, logFile = sys.stdout, version = print("Do maven clean package validate") cmd = [mvnCmd] cmd.append("-Dvaadin.version=%s" % (version)) + # Enforcer does not always seem to take vaadin.version into account, skip until this can be resolved + cmd.append("-Denforcer.skip=true") if mavenParams is not None: cmd.extend(mavenParams.strip('"').split(" ")) cmd.extend(["clean", "package", "validate"]) diff --git a/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java b/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java index 345ac25848..5d198a6488 100644 --- a/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java +++ b/server/src/main/java/com/vaadin/annotations/VaadinServletConfiguration.java @@ -122,11 +122,14 @@ public @interface VaadinServletConfiguration { /** * The default widgetset to use for the servlet. The default value is - * <code>com.vaadin.DefaultWidgetSet</code>. + * <code>""</code>, which will cause + * <code>com.vaadin.DefaultWidgetSet</code> to be used unless overridden by + * an init parameter or unless an automatically generated + * <code>AppWidgetset</code> is used. * * @return the default widgetset name */ @InitParameterName(VaadinServlet.PARAMETER_WIDGETSET) - public String widgetset() default VaadinServlet.DEFAULT_WIDGETSET; + public String widgetset() default ""; } diff --git a/server/src/main/java/com/vaadin/server/UIProvider.java b/server/src/main/java/com/vaadin/server/UIProvider.java index ce3690f9a1..a652b423ff 100644 --- a/server/src/main/java/com/vaadin/server/UIProvider.java +++ b/server/src/main/java/com/vaadin/server/UIProvider.java @@ -178,15 +178,22 @@ public abstract class UIProvider implements Serializable { return new WidgetsetInfoImpl(uiWidgetset.value()); } + // Second case: We might have an init parameter, use that + String initParameterWidgetSet = event.getService() + .getDeploymentConfiguration().getWidgetset(null); + if (initParameterWidgetSet != null) { + return new WidgetsetInfoImpl(initParameterWidgetSet); + } + // Find the class AppWidgetset in the default package if one exists WidgetsetInfo info = getWidgetsetClassInfo(); - // Second case: we have a generated class called APP_WIDGETSET_NAME + // Third case: we have a generated class called APP_WIDGETSET_NAME if (info != null) { return info; } - // third case: we have an AppWidgetset.gwt.xml file + // Fourth case: we have an AppWidgetset.gwt.xml file else { InputStream resource = event.getUIClass() .getResourceAsStream("/" + APP_WIDGETSET_NAME + ".gwt.xml"); @@ -195,7 +202,7 @@ public abstract class UIProvider implements Serializable { } } - // fourth case: we are using the default widgetset + // fifth case: we are using the default widgetset return null; } diff --git a/server/src/main/java/com/vaadin/server/VaadinServlet.java b/server/src/main/java/com/vaadin/server/VaadinServlet.java index 03d47b6693..42dfde5444 100644 --- a/server/src/main/java/com/vaadin/server/VaadinServlet.java +++ b/server/src/main/java/com/vaadin/server/VaadinServlet.java @@ -268,6 +268,16 @@ public class VaadinServlet extends HttpServlet implements Constants { stringValue = value.toString(); } + if (VaadinServlet.PARAMETER_WIDGETSET.equals(name.value()) + && method.getDefaultValue().equals(stringValue)) { + // Do not set the widgetset to anything so that the + // framework can fallback to the default. Setting + // anything to the init parameter will force that into + // use and e.g. AppWidgetset will not be used even + // though it is found. + continue; + } + initParameters.setProperty(name.value(), stringValue); } catch (Exception e) { // This should never happen diff --git a/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java b/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java index c271aec09f..7aec100255 100644 --- a/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java +++ b/server/src/main/java/com/vaadin/server/widgetsetutils/ClassPathExplorer.java @@ -223,8 +223,21 @@ public class ClassPathExplorer { if (!widgetsets.containsKey(classname)) { String packagePath = packageName.replaceAll("\\.", "/"); - String basePath = location.getFile() - .replaceAll("/" + packagePath + "$", ""); + + String basePath = location.getFile(); + if (basePath.endsWith("/" + packagePath)) { + basePath = basePath.replaceAll("/" + packagePath + "$", + ""); + } else if (basePath.endsWith("/" + packagePath + "/")) { + basePath = basePath.replaceAll("/" + packagePath + "/$", + ""); + } else { + throw new IllegalStateException( + "Error trying to find base path, location (" + + location.getFile() + + ") does not end in expected '/" + + packagePath + "'"); + } try { URL url = new URL(location.getProtocol(), location.getHost(), location.getPort(), @@ -453,8 +466,8 @@ public class ClassPathExplorer { && !dirs[i].getPath().contains(File.separator + ".")) { String key = dirs[i].getCanonicalPath() + "/" + name + dirs[i].getName(); - locations.put(key, - dirs[i].getCanonicalFile().toURI().toURL()); + URL url = dirs[i].getCanonicalFile().toURI().toURL(); + locations.put(key, url); } } catch (Exception ioe) { return; diff --git a/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java b/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java index f64b43092f..951944d8ac 100644 --- a/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java +++ b/server/src/main/java/com/vaadin/server/widgetsetutils/WidgetSetBuilder.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.Reader; +import java.net.URISyntaxException; import java.net.URL; import java.util.Collection; import java.util.HashSet; @@ -44,7 +45,8 @@ import java.util.regex.Pattern; */ public class WidgetSetBuilder { - public static void main(String[] args) throws IOException { + public static void main(String[] args) + throws IOException, URISyntaxException { if (args.length == 0) { printUsage(); } else { @@ -55,7 +57,7 @@ public class WidgetSetBuilder { } public static void updateWidgetSet(final String widgetset) - throws IOException, FileNotFoundException { + throws IOException, FileNotFoundException, URISyntaxException { boolean changed = false; Map<String, URL> availableWidgetSets = ClassPathExplorer @@ -69,9 +71,8 @@ public class WidgetSetBuilder { .getWidgetsetSourceDirectory(widgetsetFileName); } - String wsFullPath = sourceUrl.getFile() + "/" + widgetsetFileName; - - File widgetsetFile = new File(wsFullPath); + File widgetsetFile = new File(new File(sourceUrl.toURI()), + widgetsetFileName); if (!widgetsetFile.exists()) { // create empty gwt module file File parent = widgetsetFile.getParentFile(); @@ -136,7 +137,7 @@ public class WidgetSetBuilder { changed = changed || !content.equals(originalContent); if (changed) { - commitChanges(wsFullPath, content); + commitChanges(widgetsetFile, content); } } else { System.out @@ -152,11 +153,10 @@ public class WidgetSetBuilder { return content.replaceFirst("<inherits name=\"" + ws + "\"[^/]*/>", ""); } - private static void commitChanges(String widgetsetfilename, String content) + private static void commitChanges(File widgetsetFile, String content) throws IOException { BufferedWriter bufferedWriter = new BufferedWriter( - new OutputStreamWriter( - new FileOutputStream(widgetsetfilename))); + new OutputStreamWriter(new FileOutputStream(widgetsetFile))); bufferedWriter.write(content); bufferedWriter.close(); } diff --git a/test/addon-using-init-param-widget-set/pom.xml b/test/addon-using-init-param-widget-set/pom.xml new file mode 100644 index 0000000000..79939e6b1b --- /dev/null +++ b/test/addon-using-init-param-widget-set/pom.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-addon-using-init-param-widget-set</artifactId> + <packaging>war</packaging> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <!-- Included to ensure AppWidgetset is an option --> + <dependency> + <groupId>com.vaadin.addon</groupId> + <artifactId>vaadin-context-menu</artifactId> + <version>0.7.4</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-client-compiled</artifactId> + <version>${project.version}</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>resources</goal> + <goal>update-widgetset</goal> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/addon-using-init-param-widget-set/src/main/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetUI.java b/test/addon-using-init-param-widget-set/src/main/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetUI.java new file mode 100644 index 0000000000..41a240e006 --- /dev/null +++ b/test/addon-using-init-param-widget-set/src/main/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetUI.java @@ -0,0 +1,25 @@ +package com.vaadin.test.addonusinginitparamwidgetset; + +import javax.servlet.annotation.WebInitParam; +import javax.servlet.annotation.WebServlet; + +import com.vaadin.addon.contextmenu.ContextMenu; +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; +import com.vaadin.ui.AbstractComponent; + +public class AddonUsingInitParamWidgetSetUI extends AbstractTestWidgetSetUI { + + @Override + protected void init(VaadinRequest vaadinRequest) { + super.init(vaadinRequest); + new ContextMenu((AbstractComponent) getContent(), true); + } + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true, initParams = @WebInitParam(name = "widgetset", value = "com.vaadin.DefaultWidgetSet")) + @VaadinServletConfiguration(ui = AddonUsingInitParamWidgetSetUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/addon-using-init-param-widget-set/src/test/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetIT.java b/test/addon-using-init-param-widget-set/src/test/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetIT.java new file mode 100644 index 0000000000..42333fb2c7 --- /dev/null +++ b/test/addon-using-init-param-widget-set/src/test/java/com/vaadin/test/addonusinginitparamwidgetset/AddonUsingInitParamWidgetSetIT.java @@ -0,0 +1,15 @@ +package com.vaadin.test.addonusinginitparamwidgetset; + +import org.junit.Test; + +import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT; + +public class AddonUsingInitParamWidgetSetIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract("com.vaadin.DefaultWidgetSet"); + assertUnknownComponentShown("com.vaadin.addon.contextmenu.ContextMenu"); + } + +}
\ No newline at end of file diff --git a/test/addon-using-no-defined-widget-set/pom.xml b/test/addon-using-no-defined-widget-set/pom.xml new file mode 100644 index 0000000000..97178f94f8 --- /dev/null +++ b/test/addon-using-no-defined-widget-set/pom.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-addon-using-no-defined-widget-set</artifactId> + <packaging>war</packaging> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.vaadin.addon</groupId> + <artifactId>vaadin-context-menu</artifactId> + <version>0.7.4</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>resources</goal> + <goal>update-widgetset</goal> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/addon-using-no-defined-widget-set/src/main/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetUI.java b/test/addon-using-no-defined-widget-set/src/main/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetUI.java new file mode 100644 index 0000000000..1893bb46e1 --- /dev/null +++ b/test/addon-using-no-defined-widget-set/src/main/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetUI.java @@ -0,0 +1,24 @@ +package com.vaadin.test.addonusingnodefinedwidgetset; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.addon.contextmenu.ContextMenu; +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; +import com.vaadin.ui.AbstractComponent; + +public class AddonUsingNoDefinedWidgetSetUI extends AbstractTestWidgetSetUI { + + @Override + protected void init(VaadinRequest vaadinRequest) { + super.init(vaadinRequest); + new ContextMenu((AbstractComponent) getContent(), true); + } + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = AddonUsingNoDefinedWidgetSetUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/addon-using-no-defined-widget-set/src/test/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetIT.java b/test/addon-using-no-defined-widget-set/src/test/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetIT.java new file mode 100644 index 0000000000..93dc5f1e77 --- /dev/null +++ b/test/addon-using-no-defined-widget-set/src/test/java/com/vaadin/test/addonusingnodefinedwidgetset/AddonUsingNoDefinedWidgetSetIT.java @@ -0,0 +1,14 @@ +package com.vaadin.test.addonusingnodefinedwidgetset; + +import org.junit.Test; + +import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT; + +public class AddonUsingNoDefinedWidgetSetIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract("AppWidgetset"); + assertNoUnknownComponentShown(); + } +}
\ No newline at end of file diff --git a/test/addon-using-own-widget-set/pom.xml b/test/addon-using-own-widget-set/pom.xml new file mode 100644 index 0000000000..fc52e47f4f --- /dev/null +++ b/test/addon-using-own-widget-set/pom.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-addon-using-own-widget-set</artifactId> + <packaging>war</packaging> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.vaadin.addon</groupId> + <artifactId>vaadin-context-menu</artifactId> + <version>0.7.4</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>resources</goal> + <goal>update-widgetset</goal> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/addon-using-own-widget-set/src/main/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetUI.java b/test/addon-using-own-widget-set/src/main/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetUI.java new file mode 100644 index 0000000000..15efad2295 --- /dev/null +++ b/test/addon-using-own-widget-set/src/main/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetUI.java @@ -0,0 +1,26 @@ +package com.vaadin.test.addonusingownwidgetset; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.addon.contextmenu.ContextMenu; +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; +import com.vaadin.ui.AbstractComponent; + +@Widgetset("com.vaadin.test.addonusingownwidgetset.AddonUsingOwnWidgetSet") +public class AddonUsingOwnWidgetSetUI extends AbstractTestWidgetSetUI { + + @Override + protected void init(VaadinRequest vaadinRequest) { + super.init(vaadinRequest); + new ContextMenu((AbstractComponent) getContent(), true); + } + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = AddonUsingOwnWidgetSetUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/addon-using-own-widget-set/src/main/resources/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSet.gwt.xml b/test/addon-using-own-widget-set/src/main/resources/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSet.gwt.xml new file mode 100644 index 0000000000..26be42e65b --- /dev/null +++ b/test/addon-using-own-widget-set/src/main/resources/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSet.gwt.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd"> +<module> + <inherits name="com.vaadin.DefaultWidgetSet" /> + + <inherits name="com.vaadin.addon.contextmenu.WidgetSet" /> +</module> diff --git a/test/addon-using-own-widget-set/src/test/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetIT.java b/test/addon-using-own-widget-set/src/test/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetIT.java new file mode 100644 index 0000000000..c22dbf8eb9 --- /dev/null +++ b/test/addon-using-own-widget-set/src/test/java/com/vaadin/test/addonusingownwidgetset/AddonUsingOwnWidgetSetIT.java @@ -0,0 +1,15 @@ +package com.vaadin.test.addonusingownwidgetset; + +import org.junit.Test; + +import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT; + +public class AddonUsingOwnWidgetSetIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract( + "com.vaadin.test.addonusingownwidgetset.AddonUsingOwnWidgetSet"); + assertNoUnknownComponentShown(); + } +}
\ No newline at end of file diff --git a/test/default-widget-set/pom.xml b/test/default-widget-set/pom.xml new file mode 100644 index 0000000000..68ee894911 --- /dev/null +++ b/test/default-widget-set/pom.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-default-widget-set</artifactId> + <packaging>war</packaging> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-client-compiled</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + +</project>
\ No newline at end of file diff --git a/test/default-widget-set/src/main/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetUI.java b/test/default-widget-set/src/main/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetUI.java new file mode 100644 index 0000000000..fb58389ece --- /dev/null +++ b/test/default-widget-set/src/main/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetUI.java @@ -0,0 +1,15 @@ +package com.vaadin.test.defaultwidgetset; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; + +public class DefaultWidgetSetUI extends AbstractTestWidgetSetUI { + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = DefaultWidgetSetUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/default-widget-set/src/test/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetIT.java b/test/default-widget-set/src/test/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetIT.java new file mode 100644 index 0000000000..8fda5812d0 --- /dev/null +++ b/test/default-widget-set/src/test/java/com/vaadin/test/defaultwidgetset/DefaultWidgetSetIT.java @@ -0,0 +1,11 @@ +package com.vaadin.test.defaultwidgetset; + +import org.junit.Test; + +public abstract class DefaultWidgetSetIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract("com.vaadin.DefaultWidgetSet"); + } +}
\ No newline at end of file diff --git a/test/own-widget-set/pom.xml b/test/own-widget-set/pom.xml new file mode 100644 index 0000000000..6ce65c868f --- /dev/null +++ b/test/own-widget-set/pom.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-own-widget-set</artifactId> + <packaging>war</packaging> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>resources</goal> + <goal>update-widgetset</goal> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/own-widget-set/src/main/java/com/vaadin/test/ownwidgetset/OwnWidgetSetUI.java b/test/own-widget-set/src/main/java/com/vaadin/test/ownwidgetset/OwnWidgetSetUI.java new file mode 100644 index 0000000000..8801dacbae --- /dev/null +++ b/test/own-widget-set/src/main/java/com/vaadin/test/ownwidgetset/OwnWidgetSetUI.java @@ -0,0 +1,17 @@ +package com.vaadin.test.ownwidgetset; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; + +@Widgetset("com.vaadin.test.ownwidgetset.OwnWidgetSet") +public class OwnWidgetSetUI extends AbstractTestWidgetSetUI { + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = OwnWidgetSetUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/own-widget-set/src/test/java/com/vaadin/test/ownwidgetset/OwnWidgetSetIT.java b/test/own-widget-set/src/test/java/com/vaadin/test/ownwidgetset/OwnWidgetSetIT.java new file mode 100644 index 0000000000..7501fbabbb --- /dev/null +++ b/test/own-widget-set/src/test/java/com/vaadin/test/ownwidgetset/OwnWidgetSetIT.java @@ -0,0 +1,14 @@ +package com.vaadin.test.ownwidgetset; + +import org.junit.Test; + +import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT; + +public class OwnWidgetSetIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract( + "com.vaadin.test.ownwidgetset.OwnWidgetSet"); + } +}
\ No newline at end of file diff --git a/test/pom.xml b/test/pom.xml new file mode 100644 index 0000000000..b1ee2fb074 --- /dev/null +++ b/test/pom.xml @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-root</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test</artifactId> + <name>vaadin-test</name> + <packaging>pom</packaging> + <properties> + <failOnMissingWebXml>false</failOnMissingWebXml> + </properties> + + <repositories> + <repository> + <id>vaadin-addons</id> + <url>http://maven.vaadin.com/vaadin-addons</url> + </repository> + </repositories> + + <dependencies> + + <!-- API DEPENDENCIES --> + <!-- Project modules --> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-themes</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Servlet 3.0 API --> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>provided</scope> + </dependency> + + + <!-- Testing --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-testbench</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <modules> + <module>widget-set-testutil</module> + <module>default-widget-set</module> + <module>own-widget-set</module> + <module>addon-using-own-widget-set</module> + <module>addon-using-no-defined-widget-set</module> + <module>addon-using-init-param-widget-set</module> + <module>space in directory</module> + <module>vaadinservletconfiguration-widget-set</module> + </modules> + + <build> + <plugins> + <plugin> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-maven-plugin</artifactId> + <version>${jetty.version}</version> + <configuration> + <scanIntervalSeconds>-1</scanIntervalSeconds> + <stopPort>8081</stopPort> + <stopWait>5</stopWait> + <stopKey>foo</stopKey> + </configuration> + <executions> + <!-- start and stop jetty (running our app) when running + integration tests --> + <execution> + <id>start-jetty</id> + <phase>pre-integration-test</phase> + <goals> + <goal>start</goal> + </goals> + </execution> + <execution> + <id>stop-jetty</id> + <phase>post-integration-test</phase> + <goals> + <goal>stop</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.github.klieber</groupId> + <artifactId>phantomjs-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>install</goal> + </goals> + <configuration> + <version>${phantomjs.version}</version> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + <plugin> + <artifactId>maven-failsafe-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + </execution> + </executions> + <configuration> + <systemPropertyVariables> + <phantomjs.binary.path>${phantomjs.binary}</phantomjs.binary.path> + </systemPropertyVariables> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/test/space in directory/pom.xml b/test/space in directory/pom.xml new file mode 100644 index 0000000000..65c3574ead --- /dev/null +++ b/test/space in directory/pom.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-space-in-directory</artifactId> + <packaging>war</packaging> + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>resources</goal> + <goal>update-widgetset</goal> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/space in directory/src/main/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryUI.java b/test/space in directory/src/main/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryUI.java new file mode 100644 index 0000000000..ccf023c871 --- /dev/null +++ b/test/space in directory/src/main/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryUI.java @@ -0,0 +1,17 @@ +package com.vaadin.test.spaceindirectory; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; + +@Widgetset("com.vaadin.test.spaceindirectory.SpaceInDirectory") +public class SpaceInDirectoryUI extends AbstractTestWidgetSetUI { + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = SpaceInDirectoryUI.class, productionMode = false) + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/space in directory/src/main/resources/com/vaadin/test/spaceindirectory/SpaceInDirectory.gwt.xml b/test/space in directory/src/main/resources/com/vaadin/test/spaceindirectory/SpaceInDirectory.gwt.xml new file mode 100644 index 0000000000..ad42d087ce --- /dev/null +++ b/test/space in directory/src/main/resources/com/vaadin/test/spaceindirectory/SpaceInDirectory.gwt.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd"> +<module> + <inherits name="com.vaadin.DefaultWidgetSet" /> +</module>
\ No newline at end of file diff --git a/test/space in directory/src/test/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryIT.java b/test/space in directory/src/test/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryIT.java new file mode 100644 index 0000000000..f8fbfb6f8a --- /dev/null +++ b/test/space in directory/src/test/java/com/vaadin/test/spaceindirectory/SpaceInDirectoryIT.java @@ -0,0 +1,15 @@ +package com.vaadin.test.spaceindirectory; + +import org.junit.Test; + +import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT; + +public class SpaceInDirectoryIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract( + "com.vaadin.test.spaceindirectory.SpaceInDirectory"); + + } +}
\ No newline at end of file diff --git a/test/vaadinservletconfiguration-widget-set/pom.xml b/test/vaadinservletconfiguration-widget-set/pom.xml new file mode 100644 index 0000000000..96a9a94d7f --- /dev/null +++ b/test/vaadinservletconfiguration-widget-set/pom.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-vaadinservletconfiguration-widget-set</artifactId> + <packaging>war</packaging> + + <dependencies> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>resources</goal> + <goal>update-widgetset</goal> + <goal>compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/vaadinservletconfiguration-widget-set/src/main/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetUI.java b/test/vaadinservletconfiguration-widget-set/src/main/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetUI.java new file mode 100644 index 0000000000..e607df30c2 --- /dev/null +++ b/test/vaadinservletconfiguration-widget-set/src/main/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetUI.java @@ -0,0 +1,16 @@ +package com.vaadin.test.vaadinservletconfigurationwidgetset; + +import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.VaadinServlet; +import com.vaadin.test.widgetset.AbstractTestWidgetSetUI; + +public class VaadinServletConfigurationWidgetSetUI + extends AbstractTestWidgetSetUI { + + @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true) + @VaadinServletConfiguration(ui = VaadinServletConfigurationWidgetSetUI.class, productionMode = false, widgetset = "com.vaadin.test.vaadinservletconfigurationwidgetset.VaadinServletConfigurationWidgetSet") + public static class MyUIServlet extends VaadinServlet { + } +}
\ No newline at end of file diff --git a/test/vaadinservletconfiguration-widget-set/src/main/resources/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSet.gwt.xml b/test/vaadinservletconfiguration-widget-set/src/main/resources/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSet.gwt.xml new file mode 100644 index 0000000000..ad42d087ce --- /dev/null +++ b/test/vaadinservletconfiguration-widget-set/src/main/resources/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSet.gwt.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd"> +<module> + <inherits name="com.vaadin.DefaultWidgetSet" /> +</module>
\ No newline at end of file diff --git a/test/vaadinservletconfiguration-widget-set/src/test/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetIT.java b/test/vaadinservletconfiguration-widget-set/src/test/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetIT.java new file mode 100644 index 0000000000..6727cef4c7 --- /dev/null +++ b/test/vaadinservletconfiguration-widget-set/src/test/java/com/vaadin/test/vaadinservletconfigurationwidgetset/VaadinServletConfigurationWidgetSetIT.java @@ -0,0 +1,14 @@ +package com.vaadin.test.vaadinservletconfigurationwidgetset; + +import org.junit.Test; + +import com.vaadin.test.defaultwidgetset.AbstractWidgetSetIT; + +public class VaadinServletConfigurationWidgetSetIT extends AbstractWidgetSetIT { + + @Test + public void appStartsUserCanInteract() { + testAppStartsUserCanInteract( + "com.vaadin.test.vaadinservletconfigurationwidgetset.VaadinServletConfigurationWidgetSet"); + } +}
\ No newline at end of file diff --git a/test/widget-set-testutil/pom.xml b/test/widget-set-testutil/pom.xml new file mode 100644 index 0000000000..3dcc6db865 --- /dev/null +++ b/test/widget-set-testutil/pom.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-test</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + <artifactId>vaadin-test-widget-set-testutil</artifactId> + <packaging>jar</packaging> + + <dependencies> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + +</project>
\ No newline at end of file diff --git a/test/widget-set-testutil/src/main/java/com/vaadin/test/widgetset/AbstractTestWidgetSetUI.java b/test/widget-set-testutil/src/main/java/com/vaadin/test/widgetset/AbstractTestWidgetSetUI.java new file mode 100644 index 0000000000..c03645517a --- /dev/null +++ b/test/widget-set-testutil/src/main/java/com/vaadin/test/widgetset/AbstractTestWidgetSetUI.java @@ -0,0 +1,39 @@ +package com.vaadin.test.widgetset; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +public abstract class AbstractTestWidgetSetUI extends UI { + + @Override + protected void init(VaadinRequest vaadinRequest) { + final VerticalLayout layout = new VerticalLayout(); + final Label widgetsetInfo = new Label(); + widgetsetInfo.setId("widgetsetinfo"); + final TextField name = new TextField(); + name.setCaption("Type your name here:"); + + Button button = new Button("Click Me"); + button.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent clickEvent) { + layout.addComponent( + new Label("Thanks " + name.getValue() + ", it works!")); + } + }); + + getPage().getJavaScript().execute( + "widgetsetinfo.innerText=document.querySelector('iframe').id;"); + layout.addComponents(widgetsetInfo, name, button); + layout.setMargin(true); + layout.setSpacing(true); + + setContent(layout); + } + +}
\ No newline at end of file diff --git a/test/widget-set-testutil/src/test/java/com/vaadin/test/defaultwidgetset/AbstractWidgetSetIT.java b/test/widget-set-testutil/src/test/java/com/vaadin/test/defaultwidgetset/AbstractWidgetSetIT.java new file mode 100644 index 0000000000..e84296819c --- /dev/null +++ b/test/widget-set-testutil/src/test/java/com/vaadin/test/defaultwidgetset/AbstractWidgetSetIT.java @@ -0,0 +1,59 @@ +package com.vaadin.test.defaultwidgetset; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.phantomjs.PhantomJSDriver; + +import com.vaadin.testbench.ScreenshotOnFailureRule; +import com.vaadin.testbench.TestBenchTestCase; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TextFieldElement; + +public abstract class AbstractWidgetSetIT extends TestBenchTestCase { + + @Rule + public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule(this, + true); + + @Before + public void setup() { + // Screenshot rule tears down the driver + setDriver(new PhantomJSDriver()); + } + + protected void testAppStartsUserCanInteract(String expectedWidgetSet) { + getDriver().get("http://localhost:8080"); + + TextFieldElement nameInput = $(TextFieldElement.class).first(); + nameInput.setValue("John Dåe"); + + $(ButtonElement.class).first().click(); + + Assert.assertEquals("Label shown", 2, + $(LabelElement.class).all().size()); + + Assert.assertEquals("Thanks John Dåe, it works!", + $(LabelElement.class).get(1).getText()); + + Assert.assertEquals(expectedWidgetSet, + findElement(By.id("widgetsetinfo")).getText()); + + } + + protected void assertNoUnknownComponentShown() { + Assert.assertEquals(0, + findElements(By.className("vaadin-unknown-caption")).size()); + } + + protected void assertUnknownComponentShown(String componentClass) { + WebElement unknownComponentCaption = findElement( + By.className("vaadin-unknown-caption")); + Assert.assertTrue(unknownComponentCaption.getText().contains( + "does not contain implementation for " + componentClass)); + } + +}
\ No newline at end of file diff --git a/uitest-common/src/main/java/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest-common/src/main/java/com/vaadin/tests/tb3/AbstractTB3Test.java index 4985bc7e93..dce2c77db0 100644 --- a/uitest-common/src/main/java/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest-common/src/main/java/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -1015,17 +1015,12 @@ public abstract class AbstractTB3Test extends ParallelTest { return loadingIndicator.isDisplayed(); } - protected void waitUntilLoadingIndicatorNotVisible() { - waitUntil(new ExpectedCondition<Boolean>() { - - @Override - public Boolean apply(WebDriver input) { - WebElement loadingIndicator = input - .findElement(By.className("v-loading-indicator")); + protected void waitUntilLoadingIndicatorVisible() { + waitUntil(input -> isLoadingIndicatorVisible()); + } - return !loadingIndicator.isDisplayed(); - } - }); + protected void waitUntilLoadingIndicatorNotVisible() { + waitUntil(input -> !isLoadingIndicatorVisible()); } /** diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java new file mode 100644 index 0000000000..72a53d2f0c --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDown.java @@ -0,0 +1,44 @@ +package com.vaadin.tests.components.grid; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.data.DataSource; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Grid; + +@Theme("valo") +public class GridApplyFilterWhenScrolledDown extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid<String> grid = new Grid<>(); + + grid.addColumn("Name", Function.identity()); + + List<String> data = new ArrayList<>(); + for (int i = 0; i < 1000; i++) { + data.add("Name " + i); + } + + data.add("Test"); + grid.setItems(data); + + addComponent(grid); + Button button = new Button("Filter Test item", + event -> filter(grid.getDataSource(), data)); + addComponent(button); + } + + private void filter(DataSource<String> dataSource, List<String> data) { + String last = data.get(data.size() - 1); + data.clear(); + data.add(last); + dataSource.refreshAll(); + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java index 7fa86b6522..0abf48baeb 100644 --- a/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridColumnHiding.java @@ -41,10 +41,14 @@ public class GridColumnHiding extends AbstractTestUI { grid.addColumnVisibilityChangeListener(event -> visibilityChangeLabel .setValue(event.getColumn().isHidden() + "")); + Button toggleHidden = new Button("Toggle all column hidden state", + event -> grid.getColumns().forEach( + column -> column.setHidden(!column.isHidden()))); + grid.setItems(Arrays.asList(Person.createTestPerson1(), Person.createTestPerson2())); addComponents(grid, toggleNameColumn, toggleAgeColumn, - toggleEmailColumn, visibilityChangeLabel); + toggleEmailColumn, visibilityChangeLabel, toggleHidden); } } diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java b/uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java new file mode 100644 index 0000000000..74f69ef7ab --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/InitiallyDisabledGrid.java @@ -0,0 +1,58 @@ +package com.vaadin.tests.components.grid; + +import java.util.ArrayList; +import java.util.Collection; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.ui.Button; +import com.vaadin.ui.Grid; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +public class InitiallyDisabledGrid extends UI { + + @Override + protected void init(VaadinRequest request) { + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setSizeFull(); + layout.setWidth("600px"); + layout.setHeight("600px"); + final Grid<Person> grid = createGrid(); + Button button = new Button("Enable/Disable", + event -> grid.setEnabled(!grid.isEnabled())); + + layout.addComponent(button); + VerticalLayout l = new VerticalLayout(); + l.setSizeFull(); + l.addComponent(grid); + + layout.addComponent(l); + layout.setExpandRatio(l, 1.0f); + } + + private Grid<Person> createGrid() { + // Have some data + Collection<Person> people = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + Person person = new Person(); + person.setFirstName("First " + i); + person.setLastName("Last " + i); + people.add(person); + } + // Have a container of some type to contain the data + + // Create a grid bound to the container + Grid<Person> grid = new Grid<>(); + grid.setSizeFull(); + grid.setItems(people); + grid.addColumn("firstName", Person::getFirstName); + grid.addColumn("lastNAme", Person::getLastName); + + grid.setEnabled(false); + + return grid; + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicator.java b/uitest/src/main/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicator.java new file mode 100644 index 0000000000..d318b7e5b0 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicator.java @@ -0,0 +1,38 @@ +package com.vaadin.tests.components.javascriptcomponent; + +import com.vaadin.annotations.JavaScript; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.AbstractJavaScriptComponent; +import com.vaadin.ui.JavaScriptFunction; +import com.vaadin.ui.Label; + +import elemental.json.JsonArray; + +public class JSComponentLoadingIndicator extends AbstractTestUI { + + @JavaScript({ "JSComponent.js" }) + public class JSComponent extends AbstractJavaScriptComponent { + public JSComponent() { + addFunction("test", new JavaScriptFunction() { + @Override + public void call(JsonArray arguments) { + try { + Thread.sleep(1000); + Label label = new Label("pong"); + label.addStyleName("pong"); + addComponent(label); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }); + } + } + + @Override + protected void setup(VaadinRequest request) { + addComponent(new JSComponent()); + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/tests/core/SpecialCharactersEncodingUI.java b/uitest/src/main/java/com/vaadin/tests/core/SpecialCharactersEncodingUI.java new file mode 100644 index 0000000000..974d94c03b --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/core/SpecialCharactersEncodingUI.java @@ -0,0 +1,30 @@ +package com.vaadin.tests.core; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.TextField; + +public class SpecialCharactersEncodingUI extends AbstractTestUI { + + public static String textWithZwnj = "\ufeffछुट्याउनेछन् क्ष क्ष क्ष"; + + @Override + protected void setup(VaadinRequest request) { + MenuBar menubar = new MenuBar(); + menubar.setId("menubar"); + addComponent(menubar); + menubar.addItem(textWithZwnj, null); + + Label label = new Label(textWithZwnj); + label.setId("label"); + addComponent(label); + + TextField f = new TextField("Textfield", textWithZwnj); + f.setId("textfield"); + addComponent(f); + + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/tests/resources/DownloadWithPush.java b/uitest/src/main/java/com/vaadin/tests/resources/DownloadWithPush.java new file mode 100644 index 0000000000..f3d21950f9 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/resources/DownloadWithPush.java @@ -0,0 +1,93 @@ +package com.vaadin.tests.resources; + +import java.io.IOException; +import java.io.InputStream; + +import com.vaadin.annotations.Push; +import com.vaadin.server.DownloadStream; +import com.vaadin.server.Resource; +import com.vaadin.server.StreamResource; +import com.vaadin.server.StreamResource.StreamSource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; + +@Push +public class DownloadWithPush extends AbstractTestUIWithLog { + + private static class GeneratedStream extends InputStream { + int read = 0; + int next = 'a'; + private final int size; + + public GeneratedStream(int size) { + this.size = size; + } + + @Override + public int read() throws IOException { + if (available() == 0) { + return -1; + } + + read++; + next++; + if (next > 'z') { + next = 'a'; + } + return next; + } + + @Override + public int available() throws IOException { + return size - read; + } + } + + private final class DownloadResoure extends StreamResource { + private DownloadResoure(StreamSource streamSource, String filename) { + super(streamSource, filename); + } + + @Override + public DownloadStream getStream() { + DownloadStream ds = super.getStream(); + ds.setParameter("Content-Disposition", + "attachment; filename=" + getFilename() + ";"); + return ds; + } + } + + private Resource hugeFileResource = createResource();; + private int fileSize = 300 * (1024 * 1024); + + @Override + protected void setup(VaadinRequest request) { + Button b = new Button("Download a " + + String.format("%.1f", fileSize / 1024.0 / 1024.0) + "MB file", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + getUI().getPage().open(hugeFileResource, "", false); + } + }); + addComponent(b); + } + + private Resource createResource() { + Resource hugeFileResource = new DownloadResoure(new StreamSource() { + @Override + public InputStream getStream() { + return new GeneratedStream(fileSize); + } + }, "hugefile.txt"); + return hugeFileResource; + } + + @Override + protected Integer getTicketNumber() { + return 19709; + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridCellFocusOnResetSizeWidget.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridCellFocusOnResetSizeWidget.java index 0fe861f723..d2dbf78739 100644 --- a/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridCellFocusOnResetSizeWidget.java +++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridCellFocusOnResetSizeWidget.java @@ -81,6 +81,11 @@ public class GridCellFocusOnResetSizeWidget } handler.resetDataAndSize(size); } + + @Override + public boolean isWaitingForData() { + return false; + } } private class Col extends Grid.Column<String, String[]> { diff --git a/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridClientColumnRendererConnector.java b/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridClientColumnRendererConnector.java index 904ecbf1d5..e4dce67da8 100644 --- a/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridClientColumnRendererConnector.java +++ b/uitest/src/main/java/com/vaadin/tests/widgetset/client/v7/grid/GridClientColumnRendererConnector.java @@ -69,6 +69,7 @@ public class GridClientColumnRendererConnector private int numberOfRows; private DataChangeHandler dataChangeHandler; private int latency; + private Timer timer; public DelayedDataSource(DataSource<String> ds, int latency) { this.ds = ds; @@ -78,7 +79,7 @@ public class GridClientColumnRendererConnector @Override public void ensureAvailability(final int firstRowIndex, final int numberOfRows) { - new Timer() { + timer = new Timer() { @Override public void run() { @@ -87,8 +88,10 @@ public class GridClientColumnRendererConnector dataChangeHandler.dataUpdated(firstRowIndex, numberOfRows); dataChangeHandler.dataAvailable(firstRowIndex, numberOfRows); + timer = null; } - }.schedule(latency); + }; + timer.schedule(latency); } @Override @@ -117,6 +120,11 @@ public class GridClientColumnRendererConnector // TODO Auto-generated method stub (henrik paul: 17.6.) return null; } + + @Override + public boolean isWaitingForData() { + return timer != null; + } } @Override @@ -211,8 +219,7 @@ public class GridClientColumnRendererConnector @SuppressWarnings("unchecked") public void triggerClientSortingTest() { Grid<String> grid = getWidget(); - ListSorter<String> sorter = new ListSorter<>( - grid); + ListSorter<String> sorter = new ListSorter<>(grid); // Make sorter sort the numbers in natural order sorter.setComparator( @@ -236,8 +243,7 @@ public class GridClientColumnRendererConnector @SuppressWarnings("unchecked") public void shuffle() { Grid<String> grid = getWidget(); - ListSorter<String> shuffler = new ListSorter<>( - grid); + ListSorter<String> shuffler = new ListSorter<>(grid); // Make shuffler return random order shuffler.setComparator( diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValue.java b/uitest/src/main/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValue.java new file mode 100644 index 0000000000..2119b9f21e --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValue.java @@ -0,0 +1,99 @@ +package com.vaadin.v7.tests.components.datefield; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.data.util.ObjectProperty; +import com.vaadin.v7.ui.DateField; + +/** + * Test to demonstrate how discarding of field value works with various valid + * and invalid data sources. Previously (Ticket #8069) the case where the + * content of the datasource was null was not handled correctly. This value is a + * valid data source value for the field, but discard did not actually discard + * the value or remove error markers in this cases. + * + * @author Vaadin Ltd + * + */ +public class DateFieldDiscardValue extends AbstractTestUI { + + public static final String PROP_NONULL = "A field with a valid date in the data source property"; + public static final String PROP_NULL_VALUE = "A field with a null value in the data source property"; + public static final String PROP_NULL = "A field with a null datasource property"; + + @Override + protected void setup(VaadinRequest request) { + String dateFormat = "dd/MM/yy"; + + final DateField df = new DateField(PROP_NONULL); + df.setDateFormat(dateFormat); + df.setBuffered(true); + Date date = null; + try { + date = new SimpleDateFormat(dateFormat).parse("25/07/16"); + } catch (ParseException e1) { + // This cannot happen + } + ObjectProperty<Date> prop = new ObjectProperty<>(date, Date.class); + df.setPropertyDataSource(prop); + Button button = new Button("Discard 1"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + df.discard(); + } + + }); + VerticalLayout layout = new VerticalLayout(); + HorizontalLayout hLayout = new HorizontalLayout(df, button); + layout.addComponent(hLayout); + + final DateField df1 = new DateField(PROP_NULL_VALUE); + df1.setDateFormat(dateFormat); + df1.setBuffered(true); + + prop = new ObjectProperty<>(null, Date.class); + df1.setPropertyDataSource(prop); + button = new Button("Discard 2"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + df1.discard(); + } + + }); + hLayout = new HorizontalLayout(df1, button); + layout.addComponent(hLayout); + + final DateField df2 = new DateField(PROP_NULL); + df2.setDateFormat(dateFormat); + df2.setBuffered(true); + df2.setPropertyDataSource(null); + button = new Button("Discard 3"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + df2.discard(); + } + + }); + hLayout = new HorizontalLayout(df2, button); + layout.addComponent(hLayout); + + setContent(layout); + + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDown.java b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDown.java new file mode 100644 index 0000000000..08a621c937 --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDown.java @@ -0,0 +1,64 @@ +package com.vaadin.v7.tests.components.grid; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.UI; +import com.vaadin.ui.themes.ValoTheme; +import com.vaadin.v7.data.Container.Filterable; +import com.vaadin.v7.data.Item; +import com.vaadin.v7.data.util.filter.SimpleStringFilter; +import com.vaadin.v7.event.FieldEvents.TextChangeEvent; +import com.vaadin.v7.event.FieldEvents.TextChangeListener; +import com.vaadin.v7.ui.Grid; +import com.vaadin.v7.ui.Grid.HeaderRow; +import com.vaadin.v7.ui.TextField; + +@Theme("valo") +public class GridApplyFilterWhenScrolledDown extends UI { + + private Grid grid = new Grid(); + + @Override + protected void init(VaadinRequest vaadinRequest) { + + grid.addColumn("Name", String.class); + + HeaderRow appendHeaderRow = grid.appendHeaderRow(); + TextField filter = getColumnFilter("Name"); + appendHeaderRow.getCell("Name").setComponent(filter); + + for (int i = 0; i < 1000; i++) { + Item addItem = grid.getContainerDataSource().addItem(i); + addItem.getItemProperty("Name").setValue("Name " + i); + + } + + Item addItem = grid.getContainerDataSource().addItem(1000); + addItem.getItemProperty("Name").setValue("Test"); + + // grid.scrollToStart(); + setContent(grid); + } + + private TextField getColumnFilter(final Object columnId) { + TextField filter = new TextField(); + filter.setWidth("100%"); + filter.addStyleName(ValoTheme.TEXTFIELD_TINY); + filter.addTextChangeListener(new TextChangeListener() { + SimpleStringFilter filter = null; + + @Override + public void textChange(TextChangeEvent event) { + Filterable f = (Filterable) grid.getContainerDataSource(); + if (filter != null) { + f.removeContainerFilter(filter); + } + filter = new SimpleStringFilter(columnId, event.getText(), true, + true); + f.addContainerFilter(filter); + } + }); + return filter; + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGrid.java b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGrid.java new file mode 100644 index 0000000000..53e585120e --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGrid.java @@ -0,0 +1,60 @@ +package com.vaadin.v7.tests.components.grid; + +import java.util.ArrayList; +import java.util.Collection; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.data.bean.Person; +import com.vaadin.ui.Button; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.v7.data.util.BeanItemContainer; +import com.vaadin.v7.ui.Grid; + +public class InitiallyDisabledGrid extends UI { + + @Override + protected void init(VaadinRequest request) { + VerticalLayout layout = new VerticalLayout(); + setContent(layout); + layout.setSizeFull(); + layout.setWidth("600px"); + layout.setHeight("600px"); + final Grid grid = createGrid(); + Button button = new Button("Enable/Disable", + event -> grid.setEnabled(!grid.isEnabled())); + + layout.addComponent(button); + VerticalLayout l = new VerticalLayout(); + l.setSizeFull(); + l.addComponent(grid); + + layout.addComponent(l); + layout.setExpandRatio(l, 1.0f); + } + + private Grid createGrid() { + // Have some data + Collection<Person> people = new ArrayList<>(); + for (int i = 0; i < 100; i++) { + Person person = new Person(); + person.setFirstName("First " + i); + person.setLastName("Last " + i); + people.add(person); + } + // Have a container of some type to contain the data + BeanItemContainer<Person> container = new BeanItemContainer<>( + Person.class, people); + + // Create a grid bound to the container + Grid grid = new Grid(container); + grid.setSizeFull(); + grid.setColumns("firstName", "lastName"); + + grid.setEnabled(false); + + return grid; + + } + +}
\ No newline at end of file diff --git a/uitest/src/main/java/com/vaadin/v7/tests/components/grid/basicfeatures/GridBasicFeatures.java b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/basicfeatures/GridBasicFeatures.java index a534074da0..6349405f9b 100644 --- a/uitest/src/main/java/com/vaadin/v7/tests/components/grid/basicfeatures/GridBasicFeatures.java +++ b/uitest/src/main/java/com/vaadin/v7/tests/components/grid/basicfeatures/GridBasicFeatures.java @@ -1233,6 +1233,15 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> { } }); + createBooleanAction("Toggle all column hidden state", "Columns", false, + new Command<Grid, Boolean>() { + @Override + public void execute(Grid c, Boolean value, Object data) { + for (Column col : grid.getColumns()) { + col.setHidden(!col.isHidden()); + } + } + }); createBooleanAction("All columns resizable", "Columns", false, new Command<Grid, Boolean>() { diff --git a/uitest/src/main/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUI.java b/uitest/src/main/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUI.java new file mode 100644 index 0000000000..17aa7185fb --- /dev/null +++ b/uitest/src/main/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUI.java @@ -0,0 +1,30 @@ +package com.vaadin.v7.tests.core; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.TextField; + +public class SpecialCharactersEncodingUI extends AbstractTestUI { + + public static String textWithZwnj = "\ufeffछुट्याउनेछन् क्ष क्ष क्ष"; + + @Override + protected void setup(VaadinRequest request) { + MenuBar menubar = new MenuBar(); + menubar.setId("menubar"); + addComponent(menubar); + menubar.addItem(textWithZwnj, null); + + Label label = new Label(textWithZwnj); + label.setId("label"); + addComponent(label); + + TextField f = new TextField("Textfield", textWithZwnj); + f.setId("textfield"); + addComponent(f); + + } + +}
\ No newline at end of file diff --git a/uitest/src/main/resources/com/vaadin/tests/components/javascriptcomponent/JSComponent.js b/uitest/src/main/resources/com/vaadin/tests/components/javascriptcomponent/JSComponent.js new file mode 100644 index 0000000000..522654a930 --- /dev/null +++ b/uitest/src/main/resources/com/vaadin/tests/components/javascriptcomponent/JSComponent.js @@ -0,0 +1,11 @@ +com_vaadin_tests_components_javascriptcomponent_JSComponentLoadingIndicator_JSComponent = function() +{ + var connector = this; + var e = this.getElement(); + + e.innerText="click me to ping server"; + e.id="js"; + e.addEventListener("click", function() { + connector.test(); + }); +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java new file mode 100644 index 0000000000..8e18aeedd1 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java @@ -0,0 +1,44 @@ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridApplyFilterWhenScrolledDownTest extends MultiBrowserTest { + + @Test + public void scrolledCorrectly() throws InterruptedException { + openTestURL(); + final GridElement grid = $(GridElement.class).first(); + grid.scrollToRow(50); + $(ButtonElement.class).first().click(); + final TestBenchElement gridBody = grid.getBody(); + // Can't use element API because it scrolls + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + return gridBody.findElements(By.className("v-grid-row")) + .size() == 1; + } + }); + WebElement cell = gridBody.findElements(By.className("v-grid-cell")) + .get(0); + Assert.assertEquals("Test", cell.getText()); + + int gridHeight = grid.getSize().getHeight(); + int scrollerHeight = grid.getVerticalScroller().getSize().getHeight(); + Assert.assertTrue( + "Scroller height is " + scrollerHeight + + ", should be smaller than grid height: " + gridHeight, + scrollerHeight < gridHeight); + } +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnHidingTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnHidingTest.java index e0ec3edbd8..dca31e5249 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnHidingTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/GridColumnHidingTest.java @@ -15,15 +15,20 @@ */ package com.vaadin.tests.components.grid; +import static org.junit.Assert.assertEquals; + import java.util.List; import org.junit.Assert; import org.junit.Test; +import org.openqa.selenium.Dimension; import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; import com.vaadin.testbench.By; import com.vaadin.testbench.customelements.GridElement; import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.LabelElement; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -119,6 +124,30 @@ public class GridColumnHidingTest extends MultiBrowserTest { "custom age column caption".equals(elements.get(1).getText())); } + @Test + public void testShrinkColumnToZeroWithHiddenColumn() { + openTestURL(); + + // hide all + $(ButtonElement.class).get(3).click(); + + ButtonElement toggleNameColumn = $(ButtonElement.class).get(0); + ButtonElement toggleEmailColumn = $(ButtonElement.class).get(2); + + // Show + toggleNameColumn.click(); + toggleEmailColumn.click(); + + GridElement gridElement = $(GridElement.class).first(); + + GridCellElement cell = gridElement.getCell(0, 1); + dragResizeColumn(1, 0, -cell.getSize().getWidth()); + assertGreaterOrEqual("Cell got too small.", cell.getSize().getWidth(), + 10); + assertEquals(gridElement.getCell(0, 0).getLocation().getY(), + gridElement.getCell(0, 1).getLocation().getY()); + } + protected WebElement getSidebarOpenButton(GridElement grid) { List<WebElement> elements = grid .findElements(By.className("v-grid-sidebar-button")); @@ -146,4 +175,15 @@ public class GridColumnHidingTest extends MultiBrowserTest { By.className("v-grid-sidebar-popup")); return elements.isEmpty() ? null : elements.get(0); } + + private void dragResizeColumn(int columnIndex, int posX, int offset) { + GridElement gridElement = $(GridElement.class).first(); + + GridCellElement headerCell = gridElement.getHeaderCell(0, columnIndex); + Dimension size = headerCell.getSize(); + new Actions(getDriver()) + .moveToElement(headerCell, size.getWidth() + posX, + size.getHeight() / 2) + .clickAndHold().moveByOffset(offset, 0).release().perform(); + } } diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/InitiallyDisabledGridTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/InitiallyDisabledGridTest.java new file mode 100644 index 0000000000..e57b8d3efe --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/grid/InitiallyDisabledGridTest.java @@ -0,0 +1,45 @@ +package com.vaadin.tests.components.grid; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.customelements.GridElement; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class InitiallyDisabledGridTest extends SingleBrowserTest { + + @Test + public void columnsExpanded() { + openTestURL(); + + List<WebElement> cells = findElements(By.className("v-grid-cell")); + WebElement col0 = cells.get(0); + WebElement col1 = cells.get(1); + Assert.assertTrue(col0.getSize().getWidth() > 250); + Assert.assertTrue(col1.getSize().getWidth() > 250); + } + + @Test + @Ignore + /* + * The test fails at the moment because of issues related (or exactly the + * same) as https://github.com/vaadin/framework8-issues/issues/286. It + * should be enabled once it's fixed. + */ + public void worksWhenEnabled() { + openTestURL(); + $(ButtonElement.class).first().click(); + + GridElement grid = $(GridElement.class).first(); + grid.scrollToRow(80); + GridCellElement col0 = grid.getCell(80, 0); + Assert.assertEquals("First 80", col0.getText()); + } +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicatorTest.java b/uitest/src/test/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicatorTest.java new file mode 100644 index 0000000000..4532b22937 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/components/javascriptcomponent/JSComponentLoadingIndicatorTest.java @@ -0,0 +1,29 @@ +package com.vaadin.tests.components.javascriptcomponent; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class JSComponentLoadingIndicatorTest extends SingleBrowserTest { + + @Test + public void ensureLoadingIndicatorShown() { + openTestURL(); + testBench().disableWaitForVaadin(); + + WebElement js = findElement(By.id("js")); + js.click(); + waitUntilLoadingIndicatorVisible(); + waitUntilLoadingIndicatorNotVisible(); + Assert.assertEquals(1, findElements(By.className("pong")).size()); + + js.click(); + waitUntilLoadingIndicatorVisible(); + waitUntilLoadingIndicatorNotVisible(); + Assert.assertEquals(2, findElements(By.className("pong")).size()); + } + +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabsheetScrollIntoViewTest.java b/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabsheetScrollIntoViewTest.java index 57e2714105..074d952889 100644 --- a/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabsheetScrollIntoViewTest.java +++ b/uitest/src/test/java/com/vaadin/tests/components/tabsheet/TabsheetScrollIntoViewTest.java @@ -21,13 +21,24 @@ import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.TabSheetElement; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; public class TabsheetScrollIntoViewTest extends MultiBrowserTest { + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + List<DesiredCapabilities> browsers = super.getBrowsersToTest(); + // For whatever reason, IE8 never returns from the + // $(TabSheetElement.class).first() call + browsers.remove(Browser.IE8.getDesiredCapabilities()); + return browsers; + } + @Test public void scrollIntoView() { openTestURL(); diff --git a/uitest/src/test/java/com/vaadin/tests/core/SpecialCharactersEncodingUITest.java b/uitest/src/test/java/com/vaadin/tests/core/SpecialCharactersEncodingUITest.java new file mode 100644 index 0000000000..03a441623b --- /dev/null +++ b/uitest/src/test/java/com/vaadin/tests/core/SpecialCharactersEncodingUITest.java @@ -0,0 +1,37 @@ +package com.vaadin.tests.core; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.MenuBarElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class SpecialCharactersEncodingUITest extends SingleBrowserTest { + + @Test + public void checkEncoding() { + openTestURL(); + String textFieldValue = $(TextFieldElement.class).id("textfield") + .getValue(); + Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj, + textFieldValue); + LabelElement label = $(LabelElement.class).id("label"); + String labelValue = getHtml(label); // getText() strips some characters + Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj, + labelValue); + + MenuBarElement menubar = $(MenuBarElement.class).first(); + WebElement menuItem = menubar + .findElement(By.className("v-menubar-menuitem-caption")); + Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj, + getHtml(menuItem)); + } + + private String getHtml(WebElement element) { + return element.getAttribute("innerHTML"); + } +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValueTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValueTest.java new file mode 100644 index 0000000000..e215370560 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/datefield/DateFieldDiscardValueTest.java @@ -0,0 +1,85 @@ +package com.vaadin.v7.tests.components.datefield; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class DateFieldDiscardValueTest extends SingleBrowserTest { + + @Test + public void discardWhenDatasourceContentNonNullInvalidValue() { + discardWorks(DateFieldDiscardValue.PROP_NONULL, "1", "123", "25/07/16"); + } + + @Test + public void discardWhenDatasourceContentNonNullValidValue() { + discardWorks(DateFieldDiscardValue.PROP_NONULL, "1", "24/07/16", + "25/07/16"); + } + + @Test + public void discardWhenDatasourceContentNullInvalidValue() { + discardWorks(DateFieldDiscardValue.PROP_NULL_VALUE, "2", "123", ""); + } + + @Test + public void discardWhenDatasourceContentNullValidValue() { + discardWorks(DateFieldDiscardValue.PROP_NULL_VALUE, "2", "24/07/16", + ""); + } + + @Test + public void discardWhenDatasourceNull() { + // If the data source is null, discard should do nothing. + discardDoesntWork(DateFieldDiscardValue.PROP_NULL, "3", "123"); + } + + private void discardWorks(String caption, String id, String dateValue, + String resultValue) { + openTestURL(); + + ButtonElement discardButton = $(ButtonElement.class) + .caption("Discard " + id).first(); + DateFieldElement dateField = $(DateFieldElement.class).caption(caption) + .first(); + dateField.setValue(dateValue); + + discardButton.click(); + + assertEquals(resultValue, dateField.getValue()); + + List<WebElement> elements = driver + .findElements(By.className("v-errorindicator")); + + assertEquals(0, elements.size()); + } + + private void discardDoesntWork(String caption, String id, + String dateValue) { + openTestURL(); + + ButtonElement discardButton = $(ButtonElement.class) + .caption("Discard " + id).first(); + DateFieldElement dateField = $(DateFieldElement.class).caption(caption) + .first(); + dateField.setValue(dateValue); + + discardButton.click(); + + assertEquals(dateValue, dateField.getValue()); + + List<WebElement> elements = driver + .findElements(By.className("v-errorindicator")); + + assertEquals(1, elements.size()); + } + +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java new file mode 100644 index 0000000000..9a14c01146 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/GridApplyFilterWhenScrolledDownTest.java @@ -0,0 +1,44 @@ +package com.vaadin.v7.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridApplyFilterWhenScrolledDownTest extends MultiBrowserTest { + + @Test + public void scrolledCorrectly() throws InterruptedException { + openTestURL(); + final GridElement grid = $(GridElement.class).first(); + grid.scrollToRow(50); + $(TextFieldElement.class).first().setValue("Test"); + final TestBenchElement gridBody = grid.getBody(); + // Can't use element API because it scrolls + waitUntil(new ExpectedCondition<Boolean>() { + + @Override + public Boolean apply(WebDriver input) { + return gridBody.findElements(By.className("v-grid-row")) + .size() == 1; + } + }); + WebElement cell = gridBody.findElements(By.className("v-grid-cell")) + .get(0); + Assert.assertEquals("Test", cell.getText()); + + int gridHeight = grid.getSize().getHeight(); + int scrollerHeight = grid.getVerticalScroller().getSize().getHeight(); + Assert.assertTrue( + "Scroller height is " + scrollerHeight + + ", should be smaller than grid height: " + gridHeight, + scrollerHeight < gridHeight); + } +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGridTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGridTest.java new file mode 100644 index 0000000000..8f012eed25 --- /dev/null +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/InitiallyDisabledGridTest.java @@ -0,0 +1,34 @@ +package com.vaadin.v7.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class InitiallyDisabledGridTest extends SingleBrowserTest { + + @Test + public void columnsExpanded() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + GridCellElement col0 = grid.getCell(0, 0); + GridCellElement col1 = grid.getCell(0, 1); + Assert.assertTrue(col0.getSize().getWidth() > 250); + Assert.assertTrue(col1.getSize().getWidth() > 250); + } + + @Test + public void worksWhenEnabled() { + openTestURL(); + $(ButtonElement.class).first().click(); + + GridElement grid = $(GridElement.class).first(); + grid.scrollToRow(80); + GridCellElement col0 = grid.getCell(80, 0); + Assert.assertEquals("First 80", col0.getText()); + } +}
\ No newline at end of file diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnResizeTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnResizeTest.java index 22bea4f9f5..fda42e7739 100644 --- a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnResizeTest.java +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnResizeTest.java @@ -146,4 +146,25 @@ public class GridColumnResizeTest extends GridBasicFeaturesTest { assertGreaterOrEqual("Cell got too small.", cell.getSize().getWidth(), 10); } + + @Test + public void testShrinkColumnToZeroWithHiddenColumn() { + openTestURL(); + selectMenuPath("Component", "Columns", + "Toggle all column hidden state"); + // Hides although already hidden + selectMenuPath("Component", "Columns", "Column 0", "Hidden"); + // Shows + selectMenuPath("Component", "Columns", "Column 0", "Hidden"); + // Hides although already hidden + selectMenuPath("Component", "Columns", "Column 2", "Hidden"); + // Shows + selectMenuPath("Component", "Columns", "Column 2", "Hidden"); + GridCellElement cell = getGridElement().getCell(0, 1); + dragResizeColumn(1, 0, -cell.getSize().getWidth()); + assertGreaterOrEqual("Cell got too small.", cell.getSize().getWidth(), + 10); + assertEquals(getGridElement().getCell(0, 0).getLocation().getY(), + getGridElement().getCell(0, 1).getLocation().getY()); + } } diff --git a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java index 65fe0e7dee..b63da5ce30 100644 --- a/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java +++ b/uitest/src/test/java/com/vaadin/v7/tests/components/grid/basicfeatures/server/GridColumnVisibilityTest.java @@ -21,9 +21,11 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.v7.tests.components.grid.basicfeatures.GridBasicFeaturesTest; @@ -295,6 +297,35 @@ public class GridColumnVisibilityTest extends GridBasicFeaturesTest { verifyColumnNotFrozen(2); } + @Test + public void showColumnAndScrollbarWhenScrolledDownAndVisibleRowsChange() + throws Exception { + // Set a (un)suitable height + selectMenuPath("Component", "Size", "HeightMode Row"); + selectMenuPath("Component", "Size", "Height by Rows", "4.33 rows"); + + toggleAllColumnsHidable(); + + // Hide all but the first 3 + getSidebarOpenButton().click(); + for (int i = 3; i < 12; i++) { + getColumnHidingToggle(i).click(); + } + + getSidebarOpenButton().click(); + + // Scroll all the way to the end + $(GridElement.class).first().scrollToRow(999); + + // Show the fourth column + getSidebarOpenButton().click(); + getColumnHidingToggle(3).click(); + + // Make sure that the new column contains the data it should + Assert.assertEquals("(999, 3)", + getGridElement().getCell(999, 3).getText()); + } + private void verifyColumnFrozen(int index) { assertTrue(getGridElement().getHeaderCell(0, index).isFrozen()); } @@ -307,6 +338,10 @@ public class GridColumnVisibilityTest extends GridBasicFeaturesTest { selectMenuPath("Component", "Columns", "Column " + index, "Hidable"); } + private void toggleAllColumnsHidable() { + selectMenuPath("Component", "Columns", "All columns hidable"); + } + private void addRemoveColumn(int index) { selectMenuPath("Component", "Columns", "Column " + index, "Add / Remove"); diff --git a/uitest/src/test/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUITest.java b/uitest/src/test/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUITest.java new file mode 100644 index 0000000000..02cad362eb --- /dev/null +++ b/uitest/src/test/java/com/vaadin/v7/tests/core/SpecialCharactersEncodingUITest.java @@ -0,0 +1,37 @@ +package com.vaadin.v7.tests.core; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.MenuBarElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class SpecialCharactersEncodingUITest extends SingleBrowserTest { + + @Test + public void checkEncoding() { + openTestURL(); + String textFieldValue = $(TextFieldElement.class).id("textfield") + .getValue(); + Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj, + textFieldValue); + LabelElement label = $(LabelElement.class).id("label"); + String labelValue = getHtml(label); // getText() strips some characters + Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj, + labelValue); + + MenuBarElement menubar = $(MenuBarElement.class).first(); + WebElement menuItem = menubar + .findElement(By.className("v-menubar-menuitem-caption")); + Assert.assertEquals(SpecialCharactersEncodingUI.textWithZwnj, + getHtml(menuItem)); + } + + private String getHtml(WebElement element) { + return element.getAttribute("innerHTML"); + } +}
\ No newline at end of file |