diff options
author | Jonatan Kronqvist <jonatan@vaadin.com> | 2014-05-05 15:54:07 +0300 |
---|---|---|
committer | Jonatan Kronqvist <jonatan@vaadin.com> | 2014-05-05 15:55:23 +0300 |
commit | b4419682412c64a4e1a89dadfe11b9f8c2051994 (patch) | |
tree | e20ce715b6cdead2bad6a2e5c3af17a3f74e1bc6 | |
parent | 3cd07c2d0786914df0fd8024dcc7255e1e77ef76 (diff) | |
parent | 493432007d74449fe6b09b07e5becf2d07f8d183 (diff) | |
download | vaadin-framework-b4419682412c64a4e1a89dadfe11b9f8c2051994.tar.gz vaadin-framework-b4419682412c64a4e1a89dadfe11b9f8c2051994.zip |
Merge branch 'origin/master' into 7.2
* 2efe580 - Fast-forward DateField only with left mouse button (#8012) <Teemu Pöntelin>
* c98286e - Set explicit left alignment instead of removing text-align style (#13399). <Denis Anisimov>
* 16bcacd - Modified vaadinBootstrap to send v-loc as POST instead of GET (#13685). <Tapio Aali>
* a3311d8 - Prevent scroll position reset on GridLayout hierarchy change (#13386) <Johannes Dahlström>
* 98be6b1 - Replace DragStartModes TB2 test with TB3 test <Teemu Suo-Anttila>
* 43a2943 - Avoid client side exception on DnD for empty table (#13655). <Denis Anisimov>
* 0897607 - Fix ComboBox cleared suggestion popup on ItemSetChange (#13635) <Teemu Suo-Anttila>
* 813559e - Fix Table width calculation when adding the first item (#13592) <Juuso Valli>
* 9768fa5 - Ensure session is set before writing timeout interval (#13617) <Artur Signell>
* c8bc4d7 - Fix ComboBox popup scrolling when paging disabled (#13488) <mtzukanov>
* 6a67b0b - Fix TextArea with enter keyboard shortcut (#12424) <Markus Koivisto>
* f70a567 - Update uitest/ivy.xml to use TestBench 4.0.0.alpha1 (#13625) <Teemu Suo-Anttila>
* 6b6863f - Apply layout after remove tab in Accordion (#11366, #13423) <Denis Anisimov>
* cf8b765 - Fix missing TreeTable column lines in IE8 (#12989) <Juuso Valli>
* 2cfa64d - Fix Table.sort(...) to update the sort indicator (#8978) <Juuso Valli>
* 8e632ae - Report an error if RPC interface is parameterized (#10392). <Denis Anisimov>
* a32a15c - Disable test which changes global behavior of the servlet <Artur Signell>
* 0a5eeec - Support running tests on PhantomJS <Artur Signell>
* 716046a - Clarify comments in Table.typeIsCompatible (#8168) <Juuso Valli>
* 2e58e97 - Fix findUI throwing NullPointerException when extending Vaadin (#13556) <Juuso Valli>
* eeb956b - Add caching support for PublishedFileHandler (#13574) <Juuso Valli>
* c9bc18c - Fixed javadoc XHTML to HTML and fixed typos (#13518) <Markus Koivisto>
* e778184 - Clean Table.propertyValueConverters if the property is removed (#8168) <Juuso Valli>
* 5a97058 - Javadoc fix <Artur Signell>
* 134c3bb - Clarify lock check assert message if another session is locked (#13473) <Leif Åstrand>
* 83b40dd - Fix test depending on default locale <Juuso Valli>
* 9bdf3f1 - Use getChildComponents in PopupView instead of getChildren (#13503) <Denis Anisimov>
* 4709b75 - (gerrit/master) ContainerEventProvider returns style names from container. Fixes #10718 <Maciej Przepióra>
* c6a7c81 - Remove redundant toggling of calendarToggle enabled state (#13124) <Leif Åstrand>
* cfbcaaf - Drag image for text-area should contain text of text-area (#13557). <Denis Anisimov>
* 0cb1704 - Disable/enable text field for DateField on setEnable() method (#13124). <Denis Anisimov>
* c544c6c - Fix copyright headers not passing the validation <Leif Åstrand>
Change-Id: I5e4899619f3af22ee15486c2135c1160b6ac0ecc
70 files changed, 2710 insertions, 198 deletions
diff --git a/WebContent/VAADIN/themes/base/treetable/treetable.scss b/WebContent/VAADIN/themes/base/treetable/treetable.scss index 934e66097c..e4d41eefa8 100644 --- a/WebContent/VAADIN/themes/base/treetable/treetable.scss +++ b/WebContent/VAADIN/themes/base/treetable/treetable.scss @@ -26,7 +26,6 @@ .#{$primaryStyleName} .v-table-row .v-table-cell-content, .#{$primaryStyleName} .v-table-row-odd .v-table-cell-content { - position: relative; z-index: 10; } diff --git a/WebContent/VAADIN/themes/tests-table/styles.css b/WebContent/VAADIN/themes/tests-table/styles.css new file mode 100644 index 0000000000..78193c0982 --- /dev/null +++ b/WebContent/VAADIN/themes/tests-table/styles.css @@ -0,0 +1,5 @@ +@import url(../reindeer/legacy-styles.css); + +.v-table-footer-container, .v-table-cell-wrapper { + text-align: center; +} diff --git a/WebContent/VAADIN/vaadinBootstrap.js b/WebContent/VAADIN/vaadinBootstrap.js index bab759b812..fc0fb9b948 100644 --- a/WebContent/VAADIN/vaadinBootstrap.js +++ b/WebContent/VAADIN/vaadinBootstrap.js @@ -108,29 +108,29 @@ // No special url defined, use the same URL that loaded this page (without the fragment) url = window.location.href.replace(/#.*/,''); } - url += ((/\?/).test(url) ? "&" : "?") + "v-browserDetails=1"; + // Timestamp to avoid caching + url += ((/\?/).test(url) ? "&" : "?") + "v-" + (new Date()).getTime(); + + var params = "v-browserDetails=1"; var rootId = getConfig("v-rootId"); if (rootId !== undefined) { - url += "&v-rootId=" + rootId; + params += "&v-rootId=" + rootId; } // Tell the UI what theme it is configured to use var theme = getConfig('theme'); if (theme !== undefined) { - url += '&theme=' + encodeURIComponent(theme); + params += '&theme=' + encodeURIComponent(theme); } - url += "&v-appId=" + appId; + params += "&v-appId=" + appId; var extraParams = getConfig('extraParams') if (extraParams !== undefined) { - url += extraParams; + params += extraParams; } - url += '&' + vaadin.getBrowserDetailsParameters(appId); - - // Timestamp to avoid caching - url += '&v-' + (new Date()).getTime(); + params += '&' + vaadin.getBrowserDetailsParameters(appId); var r; try { @@ -168,7 +168,9 @@ } } }; - r.send(null); + // send parameters as POST data + r.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + r.send(params); log('sending request to ', url); }; @@ -239,8 +241,8 @@ }, getBrowserDetailsParameters: function(parentElementId) { // Screen height and width - var url = 'v-sh=' + window.screen.height; - url += '&v-sw=' + window.screen.width; + var params = 'v-sh=' + window.screen.height; + params += '&v-sw=' + window.screen.width; // Window height and width var cw = 0; @@ -254,12 +256,12 @@ cw = document.documentElement.clientWidth; ch = document.documentElement.clientHeight; } - url += '&v-cw=' + cw + '&v-ch=' + ch; + params += '&v-cw=' + cw + '&v-ch=' + ch; var d = new Date(); - url += '&v-curdate=' + d.getTime(); + params += '&v-curdate=' + d.getTime(); var tzo1 = d.getTimezoneOffset(); // current offset var dstDiff = 0; @@ -276,29 +278,29 @@ } // Time zone offset - url += '&v-tzo=' + tzo1; + params += '&v-tzo=' + tzo1; // DST difference - url += '&v-dstd=' + dstDiff; + params += '&v-dstd=' + dstDiff; // Raw time zone offset - url += '&v-rtzo=' + rtzo; + params += '&v-rtzo=' + rtzo; // DST in effect? - url += '&v-dston=' + (tzo1 != rtzo); + params += '&v-dston=' + (tzo1 != rtzo); var pe = document.getElementById(parentElementId); if (pe) { - url += '&v-vw=' + pe.offsetWidth; - url += '&v-vh=' + pe.offsetHeight; + params += '&v-vw=' + pe.offsetWidth; + params += '&v-vh=' + pe.offsetHeight; } // Location - url += '&v-loc=' + encodeURIComponent(location.href); + params += '&v-loc=' + encodeURIComponent(location.href); // Window name if (window.name) { - url += '&v-wn=' + encodeURIComponent(window.name); + params += '&v-wn=' + encodeURIComponent(window.name); } // Detect touch device support @@ -313,10 +315,10 @@ } if (supportsTouch) { - url += "&v-td=1"; + params += "&v-td=1"; } - return url; + return params; } }; diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java index f382562341..856f67657f 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ClientRpcVisitor.java @@ -29,6 +29,7 @@ public class ClientRpcVisitor extends TypeVisitor { @Override public void visitClientRpc(TreeLogger logger, JClassType type, ConnectorBundle bundle) throws UnableToCompleteException { + checkGenericType(logger, type); Set<? extends JClassType> hierarchy = type .getFlattenedSupertypeHierarchy(); for (JClassType subType : hierarchy) { @@ -47,6 +48,17 @@ public class ClientRpcVisitor extends TypeVisitor { } } + public static void checkGenericType(TreeLogger logger, JClassType type) + throws UnableToCompleteException { + if (type.isGenericType() != null) { + logger.log(Type.ERROR, + "Type " + type.getParameterizedQualifiedSourceName() + + "is parameterizied generic. RPC proxy " + + "for parameterizied types is not supported."); + throw new UnableToCompleteException(); + } + } + public static void checkReturnType(TreeLogger logger, JMethod method) throws UnableToCompleteException { if (!method.getReturnType().getQualifiedSourceName().equals("void")) { diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ServerRpcVisitor.java b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ServerRpcVisitor.java index 3f6ccf006f..6ad0d2fd98 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ServerRpcVisitor.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/metadata/ServerRpcVisitor.java @@ -28,6 +28,7 @@ public class ServerRpcVisitor extends TypeVisitor { @Override public void visitServerRpc(TreeLogger logger, JClassType type, ConnectorBundle bundle) throws UnableToCompleteException { + ClientRpcVisitor.checkGenericType(logger, type); bundle.setNeedsProxySupport(type); Set<? extends JClassType> superTypes = type diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index 09a5047e7c..4858b14223 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -1,6 +1,6 @@ -/* +/* * Copyright 2000-2014 Vaadin Ltd. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at @@ -65,7 +65,6 @@ import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; import com.vaadin.client.ResourceLoader.ResourceLoadEvent; import com.vaadin.client.ResourceLoader.ResourceLoadListener; import com.vaadin.client.communication.HasJavaScriptConnectorHelper; diff --git a/client/src/com/vaadin/client/extensions/ResponsiveConnector.java b/client/src/com/vaadin/client/extensions/ResponsiveConnector.java index 608a6e9df7..b2230a4846 100644 --- a/client/src/com/vaadin/client/extensions/ResponsiveConnector.java +++ b/client/src/com/vaadin/client/extensions/ResponsiveConnector.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -100,13 +100,13 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements * @return The selectors in a comma delimited string. */ protected String constructSelectorsForTarget() { - String primaryStyle = this.target.getState().primaryStyleName; + String primaryStyle = target.getState().primaryStyleName; StringBuilder selectors = new StringBuilder(); selectors.append(".").append(primaryStyle); - if (this.target.getState().styles != null - && this.target.getState().styles.size() > 0) { - for (String style : this.target.getState().styles) { + if (target.getState().styles != null + && target.getState().styles.size() > 0) { + for (String style : target.getState().styles) { selectors.append(",.").append(style); selectors.append(",.").append(primaryStyle).append(".") .append(style); @@ -118,8 +118,8 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements } // Allow the ID to be used as the selector as well for ranges - if (this.target.getState().id != null) { - selectors.append(",#").append(this.target.getState().id); + if (target.getState().id != null) { + selectors.append(",#").append(target.getState().id); } return selectors.toString(); } @@ -128,7 +128,7 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements public void onUnregister() { super.onUnregister(); LayoutManager.get(getConnection()).removeElementResizeListener( - this.target.getWidget().getElement(), this); + target.getWidget().getElement(), this); } /** @@ -314,7 +314,7 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements int height = event.getLayoutManager() .getOuterHeight(event.getElement()); - com.google.gwt.user.client.Element element = this.target.getWidget() + com.google.gwt.user.client.Element element = target.getWidget() .getElement(); boolean forceRedraw = false; @@ -323,7 +323,7 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements event.getElement()); if (!"".equals(currentWidthRanges)) { - this.target.getWidget().getElement() + target.getWidget().getElement() .setAttribute("width-range", currentWidthRanges); forceRedraw = true; } else { @@ -335,7 +335,7 @@ public class ResponsiveConnector extends AbstractExtensionConnector implements event.getElement()); if (!"".equals(currentHeightRanges)) { - this.target.getWidget().getElement() + target.getWidget().getElement() .setAttribute("height-range", currentHeightRanges); forceRedraw = true; } else { diff --git a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java index c81f798423..78c6b3146b 100644 --- a/client/src/com/vaadin/client/ui/AbstractComponentConnector.java +++ b/client/src/com/vaadin/client/ui/AbstractComponentConnector.java @@ -217,11 +217,24 @@ public abstract class AbstractComponentConnector extends AbstractConnector } + /** + * Updates the component size based on the shared state, invoking the + * {@link LayoutManager layout manager} if necessary. + */ protected void updateComponentSize() { updateComponentSize(getState().width == null ? "" : getState().width, getState().height == null ? "" : getState().height); } + /** + * Updates the component size, invoking the {@link LayoutManager layout + * manager} if necessary. + * + * @param newWidth + * The new width as a CSS string. Cannot be null. + * @param newHeight + * The new height as a CSS string. Cannot be null. + */ protected void updateComponentSize(String newWidth, String newHeight) { Profiler.enter("AbstractComponentConnector.updateComponentSize"); @@ -255,13 +268,25 @@ public abstract class AbstractComponentConnector extends AbstractConnector Profiler.leave("AbstractComponentConnector.updateComponentSize update styleNames"); Profiler.enter("AbstractComponentConnector.updateComponentSize update DOM"); - widget.setHeight(newHeight); - widget.setWidth(newWidth); + updateWidgetSize(newWidth, newHeight); Profiler.leave("AbstractComponentConnector.updateComponentSize update DOM"); Profiler.leave("AbstractComponentConnector.updateComponentSize"); } + /** + * Updates the DOM size of this connector's {@link #getWidget() widget}. + * + * @param newWidth + * The new width as a CSS string. Cannot be null. + * @param newHeight + * The new height as a CSS string. Cannot be null. + */ + protected void updateWidgetSize(String newWidth, String newHeight) { + getWidget().setWidth(newWidth); + getWidget().setHeight(newHeight); + } + @Override public boolean isRelativeHeight() { return ComponentStateUtil.isRelativeHeight(getState()); diff --git a/client/src/com/vaadin/client/ui/VCalendarPanel.java b/client/src/com/vaadin/client/ui/VCalendarPanel.java index f6c8e11c9c..5bdb3388e9 100644 --- a/client/src/com/vaadin/client/ui/VCalendarPanel.java +++ b/client/src/com/vaadin/client/ui/VCalendarPanel.java @@ -22,6 +22,7 @@ import java.util.Iterator; import com.google.gwt.aria.client.Roles; import com.google.gwt.aria.client.SelectedValue; import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.dom.client.Node; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; @@ -1498,11 +1499,12 @@ public class VCalendarPanel extends FocusableFlexTable implements */ @Override public void onMouseDown(MouseDownEvent event) { - // Allow user to click-n-hold for fast-forward or fast-rewind. + // Click-n-hold the left mouse button for fast-forward or fast-rewind. // Timer is first used for a 500ms delay after mousedown. After that has // elapsed, another timer is triggered to go off every 150ms. Both // timers are cancelled on mouseup or mouseout. - if (event.getSource() instanceof VEventButton) { + if (event.getNativeButton() == NativeEvent.BUTTON_LEFT + && event.getSource() instanceof VEventButton) { final VEventButton sender = (VEventButton) event.getSource(); processClickEvent(sender); mouseTimer = new Timer() { diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index 65422ae02e..2d080ecf3b 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -453,7 +453,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, public void scrollUp() { debug("VFS.SP.LPS: scrollUp()"); - if (currentPage + pagesToScroll > 0) { + if (pageLength > 0 && currentPage + pagesToScroll > 0) { pagesToScroll--; cancel(); schedule(200); @@ -462,8 +462,9 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, public void scrollDown() { debug("VFS.SP.LPS: scrollDown()"); - if (totalMatches > (currentPage + pagesToScroll + 1) - * pageLength) { + if (pageLength > 0 + && totalMatches > (currentPage + pagesToScroll + 1) + * pageLength) { pagesToScroll++; cancel(); schedule(200); @@ -1217,7 +1218,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * last page */ public boolean hasNextPage() { - if (totalMatches > (currentPage + 1) * pageLength) { + if (pageLength > 0 && totalMatches > (currentPage + 1) * pageLength) { return true; } else { return false; diff --git a/client/src/com/vaadin/client/ui/VPopupCalendar.java b/client/src/com/vaadin/client/ui/VPopupCalendar.java index ff20e8149b..7dea959bb4 100644 --- a/client/src/com/vaadin/client/ui/VPopupCalendar.java +++ b/client/src/com/vaadin/client/ui/VPopupCalendar.java @@ -459,6 +459,7 @@ public class VPopupCalendar extends VTextualDate implements Field, public void setEnabled(boolean enabled) { super.setEnabled(enabled); + calendarToggle.setEnabled(enabled); Roles.getButtonRole().setAriaDisabledState(calendarToggle.getElement(), !enabled); } diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 0e836907db..180d0d771b 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -3842,7 +3842,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, "right"); break; default: - DOM.setStyleAttribute(captionContainer, "textAlign", ""); + DOM.setStyleAttribute(captionContainer, "textAlign", "left"); break; } } @@ -4270,7 +4270,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } if (col.hasAttribute("width")) { - if (scrollBody == null) { + if (scrollBody == null || isNewBody) { // Already updated by setColWidth called from // TableHeads.updateCellsFromUIDL in case of a server // side resize @@ -5406,17 +5406,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } else { container.setInnerText(text); } - if (align != ALIGN_LEFT) { - switch (align) { - case ALIGN_CENTER: - container.getStyle().setProperty("textAlign", "center"); - break; - case ALIGN_RIGHT: - default: - container.getStyle().setProperty("textAlign", "right"); - break; - } - } + setAlign(align, container); setTooltip(td, description); td.appendChild(container); @@ -5454,6 +5444,21 @@ public class VScrollTable extends FlowPanel implements HasWidgets, } + private void setAlign(char align, final Element container) { + switch (align) { + case ALIGN_CENTER: + container.getStyle().setProperty("textAlign", "center"); + break; + case ALIGN_LEFT: + container.getStyle().setProperty("textAlign", "left"); + break; + case ALIGN_RIGHT: + default: + container.getStyle().setProperty("textAlign", "right"); + break; + } + } + protected void initCellWithWidget(Widget w, char align, String style, boolean sorted, final TableCellElement td) { final Element container = DOM.createDiv(); @@ -5470,21 +5475,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, td.setClassName(className); container.setClassName(VScrollTable.this.getStylePrimaryName() + "-cell-wrapper"); - // TODO most components work with this, but not all (e.g. - // Select) - // Old comment: make widget cells respect align. - // text-align:center for IE, margin: auto for others - if (align != ALIGN_LEFT) { - switch (align) { - case ALIGN_CENTER: - container.getStyle().setProperty("textAlign", "center"); - break; - case ALIGN_RIGHT: - default: - container.getStyle().setProperty("textAlign", "right"); - break; - } - } + setAlign(align, container); td.appendChild(container); getElement().appendChild(td); // ensure widget not attached to another element (possible tBody @@ -7101,7 +7092,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets, dropDetails = new TableDDDetails(); Element elementOver = drag.getElementOver(); - VScrollTableRow row = Util.findWidget(elementOver, getRowClass()); + Class<? extends Widget> clazz = getRowClass(); + VScrollTableRow row = null; + if (clazz != null) { + row = Util.findWidget(elementOver, clazz); + } if (row != null) { dropDetails.overkey = row.rowKey; Element tr = row.getElement(); @@ -7127,7 +7122,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets, private Class<? extends Widget> getRowClass() { // get the row type this way to make dd work in derived // implementations - return scrollBody.iterator().next().getClass(); + Iterator<Widget> iterator = scrollBody.iterator(); + if (iterator.hasNext()) { + return iterator.next().getClass(); + } else { + return null; + } } @Override diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index 574d8141e5..1d2c5c122f 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -324,8 +324,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, } private boolean update(TabState tabState) { - if (tabState.description != null - || tabState.componentError != null) { + if (tabState.description != null || tabState.componentError != null) { setTooltipInfo(new TooltipInfo(tabState.description, tabState.componentError)); } else { @@ -337,14 +336,11 @@ public class VTabsheet extends VTabsheetBase implements Focusable, String captionString = tabState.caption.isEmpty() ? null : tabState.caption; boolean ret = updateCaptionWithoutOwner(captionString, - !tabState.enabled, - hasAttribute(tabState.description), + !tabState.enabled, hasAttribute(tabState.description), hasAttribute(tabState.componentError), tab.getTabsheet().connector .getResourceUrl(ComponentConstants.ICON_RESOURCE - + tabState.key), - tabState.iconAltText - ); + + tabState.key), tabState.iconAltText); setClosable(tabState.closable); @@ -916,7 +912,6 @@ public class VTabsheet extends VTabsheetBase implements Focusable, DOM.setElementProperty(tabs, "className", tabsClass); DOM.setElementProperty(contentNode, "className", contentClass); DOM.setElementProperty(deco, "className", decoClass); - borderW = -1; } } else { tb.setStyleName(CLASSNAME + "-tabs"); @@ -1209,14 +1204,9 @@ public class VTabsheet extends VTabsheetBase implements Focusable, return tabPanel.iterator(); } - private int borderW = -1; - /** For internal use only. May be removed or replaced in the future. */ public int getContentAreaBorderWidth() { - if (borderW < 0) { - borderW = Util.measureHorizontalBorder(contentNode); - } - return borderW; + return Util.measureHorizontalBorder(contentNode); } @Override diff --git a/client/src/com/vaadin/client/ui/VTextArea.java b/client/src/com/vaadin/client/ui/VTextArea.java index 75c4e257dd..cc77306100 100644 --- a/client/src/com/vaadin/client/ui/VTextArea.java +++ b/client/src/com/vaadin/client/ui/VTextArea.java @@ -17,12 +17,15 @@ package com.vaadin.client.ui; import com.google.gwt.core.client.Scheduler; +import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.dom.client.Style.WhiteSpace; import com.google.gwt.dom.client.TextAreaElement; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; +import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.user.client.Command; @@ -30,6 +33,7 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.vaadin.client.BrowserInfo; import com.vaadin.client.Util; +import com.vaadin.client.ui.dd.VDragCloneAware; /** * This class represents a multiline textfield (textarea). @@ -40,15 +44,22 @@ import com.vaadin.client.Util; * @author Vaadin Ltd. * */ -public class VTextArea extends VTextField { +public class VTextArea extends VTextField implements VDragCloneAware { + public static final String CLASSNAME = "v-textarea"; private boolean wordwrap = true; private MaxLengthHandler maxLengthHandler = new MaxLengthHandler(); private boolean browserSupportsMaxLengthAttribute = browserSupportsMaxLengthAttribute(); + private EnterDownHandler enterDownHandler = new EnterDownHandler(); public VTextArea() { super(DOM.createTextArea()); setStyleName(CLASSNAME); + + // KeyDownHandler is needed for correct text input on all + // browsers, not just those that don't support a max length attribute + addKeyDownHandler(enterDownHandler); + if (!browserSupportsMaxLengthAttribute) { addKeyUpHandler(maxLengthHandler); addChangeHandler(maxLengthHandler); @@ -247,6 +258,20 @@ public class VTextArea extends VTextField { } } + private class EnterDownHandler implements KeyDownHandler { + + @Override + public void onKeyDown(KeyDownEvent event) { + // Fix for #12424 - if the key being pressed is enter, we stop + // propagation of the KeyDownEvents. This prevents shortcuts that + // are bound to the enter key from being processed. + if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + event.stopPropagation(); + } + } + + } + @Override public int getCursorPos() { // This is needed so that TextBoxImplIE6 is used to return the correct @@ -292,6 +317,17 @@ public class VTextArea extends VTextField { // Overridden to avoid submitting TextArea value on enter in IE. This is // another reason why widgets should inherit a common abstract // class instead of directly each other. + // This method is overridden only for IE and Firefox. } + @Override + public void initDragImageCopy(Element element) { + // Fix for #13557 - drag image doesn't show original text area text. + // It happens because "value" property is not copied into the cloned + // element + String value = getElement().getPropertyString("value"); + if (value != null) { + element.setPropertyString("value", value); + } + } } diff --git a/client/src/com/vaadin/client/ui/VTextualDate.java b/client/src/com/vaadin/client/ui/VTextualDate.java index f8c4d614db..b95f696030 100644 --- a/client/src/com/vaadin/client/ui/VTextualDate.java +++ b/client/src/com/vaadin/client/ui/VTextualDate.java @@ -216,6 +216,12 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, } + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + text.setEnabled(enabled); + } + protected void setPrompting(boolean prompting) { this.prompting = prompting; if (prompting) { diff --git a/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java b/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java index 2fbfacfb8e..c0caded759 100644 --- a/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java +++ b/client/src/com/vaadin/client/ui/accordion/AccordionConnector.java @@ -59,6 +59,7 @@ public class AccordionConnector extends TabsheetBaseConnector implements } else if (getWidget().getOpenStackItem() != null) { getWidget().close(getWidget().getOpenStackItem()); } + getLayoutManager().setNeedsVerticalLayout(this); } @Override diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 34c140fbe3..6c8ccf32a8 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -121,6 +121,10 @@ public class ComboBoxConnector extends AbstractFieldConnector implements boolean suggestionsChanged = !getWidget().initDone || !newSuggestions.equals(getWidget().currentSuggestions); + // An ItemSetChangeEvent on server side clears the current suggestion + // popup. Popup needs to be repopulated with suggestions from UIDL. + boolean popupOpenAndCleared = false; + oldSuggestionTextMatchTheOldSelection = false; if (suggestionsChanged) { @@ -141,6 +145,7 @@ public class ComboBoxConnector extends AbstractFieldConnector implements * menu might not necessary exist in select at all anymore. */ getWidget().suggestionPopup.menu.clearItems(); + popupOpenAndCleared = getWidget().suggestionPopup.isAttached(); } @@ -159,9 +164,9 @@ public class ComboBoxConnector extends AbstractFieldConnector implements } } - if (getWidget().waitingForFilteringResponse - && getWidget().lastFilter.toLowerCase().equals( - uidl.getStringVariable("filter"))) { + if ((getWidget().waitingForFilteringResponse && getWidget().lastFilter + .toLowerCase().equals(uidl.getStringVariable("filter"))) + || popupOpenAndCleared) { getWidget().suggestionPopup.showSuggestions( getWidget().currentSuggestions, getWidget().currentPage, getWidget().totalMatches); diff --git a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java index 6bfe9a46a9..a349eb2993 100644 --- a/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java +++ b/client/src/com/vaadin/client/ui/datefield/PopupDateFieldConnector.java @@ -103,8 +103,6 @@ public class PopupDateFieldConnector extends TextualDateConnector { getWidget().calendar.renderCalendar(); } - getWidget().calendarToggle.setEnabled(getWidget().isEnabled()); - if (getWidget().getCurrentResolution().getCalendarField() <= Resolution.MONTH .getCalendarField()) { getWidget().calendar @@ -161,7 +159,6 @@ public class PopupDateFieldConnector extends TextualDateConnector { getWidget().setDescriptionForAssistiveDevices( getState().descriptionForAssistiveDevices); - getWidget().calendarToggle.setEnabled(true); } @Override diff --git a/client/src/com/vaadin/client/ui/dd/VDragCloneAware.java b/client/src/com/vaadin/client/ui/dd/VDragCloneAware.java new file mode 100644 index 0000000000..53bc206588 --- /dev/null +++ b/client/src/com/vaadin/client/ui/dd/VDragCloneAware.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.client.ui.dd; + +import com.google.gwt.dom.client.Element; + +/** + * Widget could implement this interface if drag image requires additional + * initialization/configuration. Method {@link #initDragImageCopy(Element)} + * allows to change/correct drag image element when element is dragged via DnD. + * + * @since 7.3 + * @author Vaadin Ltd + */ +public interface VDragCloneAware { + + /** + * This method is called for cloned <code>element</code> which corresponds + * to the widget element. One could modify/correct this <code>element</code> + * for drag image. + * + * @param element + * cloned element of drag image + */ + void initDragImageCopy(Element element); +} diff --git a/client/src/com/vaadin/client/ui/dd/VDragEvent.java b/client/src/com/vaadin/client/ui/dd/VDragEvent.java index f955c55b29..dc234de46d 100644 --- a/client/src/com/vaadin/client/ui/dd/VDragEvent.java +++ b/client/src/com/vaadin/client/ui/dd/VDragEvent.java @@ -21,11 +21,14 @@ import java.util.Map; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.dom.client.Node; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.TableElement; import com.google.gwt.dom.client.TableSectionElement; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.EventListener; import com.vaadin.client.BrowserInfo; import com.vaadin.client.Util; @@ -241,6 +244,7 @@ public class VDragEvent { public void createDragImage(com.google.gwt.user.client.Element element, boolean alignImageToEvent) { Element cloneNode = (Element) element.cloneNode(true); + syncContent(element, cloneNode); if (BrowserInfo.get().isIE()) { if (cloneNode.getTagName().toLowerCase().equals("tr")) { TableElement table = Document.get().createTableElement(); @@ -277,4 +281,31 @@ public class VDragEvent { createDragImage(DOM.asOld(element), alignImageToEvent); } + /** + * Do additional content sync between <code>original</code> element and its + * <code>copy</code> if needed. + * + * @since 7.3 + * @param original + * original element + * @param copy + * copy of original element + */ + protected void syncContent(Element original, Element copy) { + for (int i = 0; i < original.getChildCount(); i++) { + Node child = original.getChild(i); + if (child instanceof Element) { + syncContent((Element) child, (Element) copy.getChild(i)); + } + } + doSyncContent(original, copy); + } + + private void doSyncContent(Element original, Element copy) { + EventListener eventListener = Event.getEventListener(original); + if (eventListener instanceof VDragCloneAware) { + ((VDragCloneAware) eventListener).initDragImageCopy(copy); + } + } + } diff --git a/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java b/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java index e7af83e1ad..67220e5c36 100644 --- a/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java +++ b/client/src/com/vaadin/client/ui/gridlayout/GridLayoutConnector.java @@ -210,4 +210,18 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector public void layoutHorizontally() { getWidget().updateWidth(); } + + @Override + protected void updateWidgetSize(String newWidth, String newHeight) { + // Prevent the element from momentarily shrinking to zero size + // when the size is set to undefined by a state change but before + // it is recomputed in the layout phase. This may affect scroll + // position in some cases; see #13386. + if (!isUndefinedHeight()) { + getWidget().setHeight(newHeight); + } + if (!isUndefinedWidth()) { + getWidget().setWidth(newWidth); + } + } } diff --git a/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java b/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java index 0cbcfb2139..bde5f6a051 100644 --- a/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java +++ b/client/src/com/vaadin/client/ui/popupview/PopupViewConnector.java @@ -97,11 +97,9 @@ public class PopupViewConnector extends AbstractHasComponentsConnector public void onConnectorHierarchyChange( ConnectorHierarchyChangeEvent connectorHierarchyChangeEvent) { // Render the popup if visible and show it. - if (!getChildren().isEmpty()) { + if (!getChildComponents().isEmpty()) { getWidget().preparePopup(getWidget().popup); - getWidget().popup - .setPopupConnector((ComponentConnector) getChildren() - .get(0)); + getWidget().popup.setPopupConnector(getChildComponents().get(0)); if (ComponentStateUtil.hasStyles(getState())) { final StringBuffer styleBuf = new StringBuffer(); final String primaryName = getWidget().popup diff --git a/server/src/com/vaadin/server/FontAwesome.java b/server/src/com/vaadin/server/FontAwesome.java index a7f4c7b342..d4ad612d45 100644 --- a/server/src/com/vaadin/server/FontAwesome.java +++ b/server/src/com/vaadin/server/FontAwesome.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 Vaadin Ltd. + * Copyright 2000-2013 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ + package com.vaadin.server; /** diff --git a/server/src/com/vaadin/server/FontIcon.java b/server/src/com/vaadin/server/FontIcon.java index 45279f2c44..6b9a55cf20 100644 --- a/server/src/com/vaadin/server/FontIcon.java +++ b/server/src/com/vaadin/server/FontIcon.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 Vaadin Ltd. + * Copyright 2000-2013 Vaadin Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. */ + package com.vaadin.server; import com.vaadin.shared.ui.label.ContentMode; diff --git a/server/src/com/vaadin/server/Responsive.java b/server/src/com/vaadin/server/Responsive.java index 36c25e9c6a..9209f14ff9 100644 --- a/server/src/com/vaadin/server/Responsive.java +++ b/server/src/com/vaadin/server/Responsive.java @@ -4,9 +4,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -49,7 +49,7 @@ import com.vaadin.ui.Component; * * <pre> * CssLayout layout = new CssLayout(); - * layout.setStyleName("responsive"); + * layout.setStyleName("responsive"); * layout.setSizeFull(); * Responsive.makeResponsive(layout); * </pre> diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index f2181c7c6f..6aeac684c2 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -985,7 +985,7 @@ public abstract class VaadinService implements Serializable { // Get UI id from the request String uiIdString = request.getParameter(UIConstants.UI_ID_PARAMETER); UI ui = null; - if (uiIdString != null) { + if (uiIdString != null && session != null) { int uiId = Integer.parseInt(uiIdString); ui = session.getUIById(uiId); } diff --git a/server/src/com/vaadin/server/communication/MetadataWriter.java b/server/src/com/vaadin/server/communication/MetadataWriter.java index b06246cceb..17c893fe40 100644 --- a/server/src/com/vaadin/server/communication/MetadataWriter.java +++ b/server/src/com/vaadin/server/communication/MetadataWriter.java @@ -77,7 +77,8 @@ public class MetadataWriter implements Serializable { // sessionExpiredURL after timer expires. if (messages != null && messages.getSessionExpiredMessage() == null && messages.getSessionExpiredCaption() == null - && messages.isSessionExpiredNotificationEnabled()) { + && messages.isSessionExpiredNotificationEnabled() + && ui.getSession().getSession() != null) { int newTimeoutInterval = ui.getSession().getSession() .getMaxInactiveInterval(); if (repaintAll || (timeoutInterval != newTimeoutInterval)) { diff --git a/server/src/com/vaadin/server/communication/PublishedFileHandler.java b/server/src/com/vaadin/server/communication/PublishedFileHandler.java index 4ebe38bff3..56edffd16d 100644 --- a/server/src/com/vaadin/server/communication/PublishedFileHandler.java +++ b/server/src/com/vaadin/server/communication/PublishedFileHandler.java @@ -110,7 +110,14 @@ public class PublishedFileHandler implements RequestHandler { return true; } - // TODO Check and set cache headers + // Set caching for the published file + String cacheControl = "public, max-age=0, must-revalidate"; + int resourceCacheTime = request.getService() + .getDeploymentConfiguration().getResourceCacheTime(); + if (resourceCacheTime > 0) { + cacheControl = "max-age=" + String.valueOf(resourceCacheTime); + } + response.setHeader("Cache-Control", cacheControl); OutputStream out = null; try { diff --git a/server/src/com/vaadin/ui/Table.java b/server/src/com/vaadin/ui/Table.java index 4c15aca2eb..b4d79f304c 100644 --- a/server/src/com/vaadin/ui/Table.java +++ b/server/src/com/vaadin/ui/Table.java @@ -2647,6 +2647,10 @@ public class Table extends AbstractSelect implements Action.Container, * new container contains properties that are not meant to be shown you * should use {@link Table#setContainerDataSource(Container, Collection)} * instead, especially if the table is editable. + * <p> + * Keeps propertyValueConverters if the corresponding id exists in the new + * data source and is of a compatible type. + * </p> * * @param newDataSource * the new data source. @@ -2681,9 +2685,14 @@ public class Table extends AbstractSelect implements Action.Container, /** * Sets the container data source and the columns that will be visible. * Columns are shown in the collection's iteration order. + * <p> + * Keeps propertyValueConverters if the corresponding id exists in the new + * data source and is of a compatible type. + * </p> * * @see Table#setContainerDataSource(Container) * @see Table#setVisibleColumns(Object[]) + * @see Table#setConverter(Object, Converter<String, ?>) * * @param newDataSource * the new data source. @@ -2702,6 +2711,26 @@ public class Table extends AbstractSelect implements Action.Container, visibleIds = new ArrayList<Object>(); } + // Retain propertyValueConverters if their corresponding ids are + // properties of the new + // data source and are of a compatible type + if (propertyValueConverters != null) { + Collection<?> newPropertyIds = newDataSource + .getContainerPropertyIds(); + LinkedList<Object> retainableValueConverters = new LinkedList<Object>(); + for (Object propertyId : newPropertyIds) { + Converter<String, ?> converter = getConverter(propertyId); + if (converter != null) { + if (typeIsCompatible(converter.getModelType(), + newDataSource.getType(propertyId))) { + retainableValueConverters.add(propertyId); + } + } + } + propertyValueConverters.keySet().retainAll( + retainableValueConverters); + } + // Assures that the data source is ordered by making unordered // containers ordered by wrapping them if (newDataSource instanceof Container.Ordered) { @@ -2738,6 +2767,20 @@ public class Table extends AbstractSelect implements Action.Container, } /** + * Checks if class b can be safely assigned to class a. + * + * @param a + * @param b + * @return + */ + private boolean typeIsCompatible(Class<?> a, Class<?> b) { + // TODO Implement this check properly + // Basically we need to do a a.isAssignableFrom(b) + // with special considerations for primitive types. + return true; + } + + /** * Gets items ids from a range of key values * * @param startRowKey @@ -4229,6 +4272,8 @@ public class Table extends AbstractSelect implements Action.Container, columnIcons.remove(propertyId); columnHeaders.remove(propertyId); columnFooters.remove(propertyId); + // If a propertyValueConverter was defined for the property, remove it. + propertyValueConverters.remove(propertyId); return super.removeContainerProperty(propertyId); } @@ -4706,7 +4751,15 @@ public class Table extends AbstractSelect implements Action.Container, if (refreshingPreviouslyEnabled) { enableContentRefreshing(true); } - + if (propertyId.length > 0 && ascending.length > 0) { + // The first propertyId is the primary sorting criterion, + // therefore the sort indicator should be there + sortAscending = ascending[0]; + sortContainerPropertyId = propertyId[0]; + } else { + sortAscending = true; + sortContainerPropertyId = null; + } } else if (c != null) { throw new UnsupportedOperationException( "Underlying Data does not allow sorting"); @@ -5844,16 +5897,13 @@ public class Table extends AbstractSelect implements Action.Container, throw new IllegalArgumentException("PropertyId " + propertyId + " must be in the container"); } - // FIXME: This check should be here but primitive types like Boolean - // formatter for boolean property must be handled - // if (!converter.getSourceType().isAssignableFrom(getType(propertyId))) - // { - // throw new IllegalArgumentException("Property type (" - // + getType(propertyId) - // + ") must match converter source type (" - // + converter.getSourceType() + ")"); - // } + if (!typeIsCompatible(converter.getModelType(), getType(propertyId))) { + throw new IllegalArgumentException("Property type (" + + getType(propertyId) + + ") must match converter source type (" + + converter.getModelType() + ")"); + } propertyValueConverters.put(propertyId, (Converter<String, Object>) converter); refreshRowCache(); diff --git a/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java b/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java index 898d957e7b..f7a69c2edb 100644 --- a/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java +++ b/server/tests/src/com/vaadin/server/VaadinPortletServiceTests.java @@ -20,8 +20,15 @@ import static org.hamcrest.core.Is.is; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.concurrent.locks.ReentrantLock; + +import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; + +import com.vaadin.shared.ui.ui.UIConstants; +import com.vaadin.ui.UI; public class VaadinPortletServiceTests { @@ -188,4 +195,28 @@ public class VaadinPortletServiceTests { assertThat(widgetset, is("com.vaadin.portal.gwt.PortalDefaultWidgetSet")); } + + @Test + public void findUIDoesntThrowNPE() { + try { + ReentrantLock mockLock = Mockito.mock(ReentrantLock.class); + when(mockLock.isHeldByCurrentThread()).thenReturn(true); + + WrappedSession emptyWrappedSession = Mockito + .mock(WrappedSession.class); + when(emptyWrappedSession.getAttribute("null.lock")).thenReturn( + mockLock); + VaadinRequest requestWithUIIDSet = Mockito + .mock(VaadinRequest.class); + when(requestWithUIIDSet.getParameter(UIConstants.UI_ID_PARAMETER)) + .thenReturn("1"); + when(requestWithUIIDSet.getWrappedSession()).thenReturn( + emptyWrappedSession); + + UI ui = sut.findUI(requestWithUIIDSet); + Assert.assertNull("Unset session did not return null", ui); + } catch (NullPointerException e) { + Assert.fail("findUI threw a NullPointerException"); + } + } } diff --git a/server/tests/src/com/vaadin/server/communication/MetadataWriterTest.java b/server/tests/src/com/vaadin/server/communication/MetadataWriterTest.java new file mode 100644 index 0000000000..dee37ddc7f --- /dev/null +++ b/server/tests/src/com/vaadin/server/communication/MetadataWriterTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server.communication; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.StringWriter; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import com.vaadin.server.SystemMessages; +import com.vaadin.server.VaadinSession; +import com.vaadin.server.WrappedSession; +import com.vaadin.ui.UI; + +public class MetadataWriterTest { + + private UI ui; + private VaadinSession session; + private StringWriter writer; + private SystemMessages messages; + + @Before + public void setup() { + ui = Mockito.mock(UI.class); + session = Mockito.mock(VaadinSession.class); + Mockito.when(ui.getSession()).thenReturn(session); + writer = new StringWriter(); + messages = Mockito.mock(SystemMessages.class); + } + + private void disableSessionExpirationMessages(SystemMessages messages) { + when(messages.isSessionExpiredNotificationEnabled()).thenReturn(true); + when(messages.getSessionExpiredMessage()).thenReturn(null); + when(messages.getSessionExpiredCaption()).thenReturn(null); + } + + @Test + public void writeAsyncTag() throws Exception { + new MetadataWriter().write(ui, writer, false, true, messages); + Assert.assertEquals("{\"async\":true}", writer.getBuffer().toString()); + } + + @Test + public void writeRepaintTag() throws Exception { + new MetadataWriter().write(ui, writer, true, false, messages); + Assert.assertEquals("{\"repaintAll\":true}", writer.getBuffer() + .toString()); + } + + @Test + public void writeRepaintAndAsyncTag() throws Exception { + new MetadataWriter().write(ui, writer, true, true, messages); + Assert.assertEquals("{\"repaintAll\":true, \"async\":true}", writer + .getBuffer().toString()); + } + + @Test + public void writeRedirectWithExpiredSession() throws Exception { + disableSessionExpirationMessages(messages); + + new MetadataWriter().write(ui, writer, false, false, messages); + Assert.assertEquals("{}", writer.getBuffer().toString()); + } + + @Test + public void writeRedirectWithActiveSession() throws Exception { + WrappedSession wrappedSession = mock(WrappedSession.class); + when(session.getSession()).thenReturn(wrappedSession); + + disableSessionExpirationMessages(messages); + + new MetadataWriter().write(ui, writer, false, false, messages); + Assert.assertEquals( + "{\"timedRedirect\":{\"interval\":15,\"url\":\"\"}}", writer + .getBuffer().toString()); + } +} diff --git a/server/tests/src/com/vaadin/tests/data/converter/TestStringToLongConverter.java b/server/tests/src/com/vaadin/tests/data/converter/TestStringToLongConverter.java index 18e2ed06c0..3210703445 100644 --- a/server/tests/src/com/vaadin/tests/data/converter/TestStringToLongConverter.java +++ b/server/tests/src/com/vaadin/tests/data/converter/TestStringToLongConverter.java @@ -51,7 +51,7 @@ public class TestStringToLongConverter extends TestCase { String.class, Locale.ENGLISH); Assert.assertEquals("9,223,372,036,854,775,807", str); str = reverseConverter.convertToModel(Long.MIN_VALUE, String.class, - null); + Locale.ENGLISH); Assert.assertEquals("-9,223,372,036,854,775,808", str); } diff --git a/server/tests/src/com/vaadin/tests/server/component/table/TablePropertyValueConverter.java b/server/tests/src/com/vaadin/tests/server/component/table/TablePropertyValueConverter.java new file mode 100644 index 0000000000..418ca333bc --- /dev/null +++ b/server/tests/src/com/vaadin/tests/server/component/table/TablePropertyValueConverter.java @@ -0,0 +1,380 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.server.component.table; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map.Entry; +import java.util.Set; + +import junit.framework.TestCase; + +import org.junit.Test; + +import com.vaadin.data.Container; +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.data.util.converter.Converter; +import com.vaadin.ui.Table; + +/** + * + * @since + * @author Vaadin Ltd + */ +public class TablePropertyValueConverter extends TestCase { + protected TestableTable table; + protected Collection<?> initialProperties; + + @Test + public void testRemovePropertyId() { + Collection<Object> converters = table.getCurrentConverters(); + assertTrue("Set of converters was empty at the start.", + converters.size() > 0); + + Object firstId = converters.iterator().next(); + + table.removeContainerProperty(firstId); + + Collection<Object> converters2 = table.getCurrentConverters(); + assertTrue("FirstId was not removed", !converters2.contains(firstId)); + + assertTrue("The number of removed converters was not one.", + converters.size() - converters2.size() == 1); + + for (Object originalId : converters) { + if (!originalId.equals(firstId)) { + assertTrue("The wrong converter was removed.", + converters2.contains(originalId)); + } + } + + } + + @Test + public void testSetContainer() { + table.setContainerDataSource(createContainer(new String[] { "col1", + "col3", "col4", "col5" })); + Collection<Object> converters = table.getCurrentConverters(); + assertTrue("There should only have been one converter left.", + converters.size() == 1); + Object onlyKey = converters.iterator().next(); + assertTrue("The incorrect key was left.", onlyKey.equals("col1")); + + } + + @Test + public void testSetContainerWithInexactButCompatibleTypes() { + TestableTable customTable = new TestableTable("Test table", + createContainer(new String[] { "col1", "col2", "col3" }, + new Class[] { String.class, BaseClass.class, + DerivedClass.class })); + customTable.setConverter("col1", new Converter<String, String>() { + private static final long serialVersionUID = 1L; + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "model"; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "presentation"; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + }); + customTable.setConverter("col2", new Converter<String, BaseClass>() { + private static final long serialVersionUID = 1L; + + @Override + public BaseClass convertToModel(String value, + Class<? extends BaseClass> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return new BaseClass("model"); + } + + @Override + public Class<BaseClass> getModelType() { + return BaseClass.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + @Override + public String convertToPresentation(BaseClass value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return null; + } + }); + customTable.setConverter("col3", new Converter<String, DerivedClass>() { + private static final long serialVersionUID = 1L; + + @Override + public DerivedClass convertToModel(String value, + Class<? extends DerivedClass> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return new DerivedClass("derived" + 1001); + } + + @Override + public Class<DerivedClass> getModelType() { + return DerivedClass.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + @Override + public String convertToPresentation(DerivedClass value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return null; + } + }); + customTable.setContainerDataSource(createContainer(new String[] { + "col1", "col2", "col3" }, new Class[] { DerivedClass.class, + DerivedClass.class, BaseClass.class })); + Set<Object> converters = customTable.getCurrentConverters(); + // TODO Test temporarily disabled as this feature + // is not yet implemented in Table + /* + * assertTrue("Incompatible types were not removed.", converters.size() + * <= 1); assertTrue("Even compatible types were removed", + * converters.size() == 1); assertTrue("Compatible type was missing.", + * converters.contains("col2")); + */ + } + + @Test + public void testPrimitiveTypeConverters() { + TestableTable customTable = new TestableTable("Test table", + createContainer(new String[] { "col1", "col2", "col3" }, + new Class[] { int.class, BaseClass.class, + DerivedClass.class })); + customTable.setConverter("col1", new Converter<String, Integer>() { + private static final long serialVersionUID = 1L; + + @Override + public Integer convertToModel(String value, + Class<? extends Integer> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return 11; + } + + @Override + public String convertToPresentation(Integer value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "presentation"; + } + + @Override + public Class<Integer> getModelType() { + return Integer.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + }); + Set<Object> converters = customTable.getCurrentConverters(); + assertTrue("Converter was not set.", converters.size() > 0); + } + + @Test + public void testInheritance() { + assertTrue("BaseClass isn't assignable from DerivedClass", + BaseClass.class.isAssignableFrom(DerivedClass.class)); + assertFalse("DerivedClass is assignable from BaseClass", + DerivedClass.class.isAssignableFrom(BaseClass.class)); + } + + @Override + public void setUp() { + table = new TestableTable("Test table", createContainer(new String[] { + "col1", "col2", "col3" })); + table.setConverter("col1", new Converter<String, String>() { + private static final long serialVersionUID = 1L; + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "model"; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "presentation"; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + }); + + table.setConverter("col2", new Converter<String, String>() { + private static final long serialVersionUID = 1L; + + @Override + public String convertToModel(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "model2"; + } + + @Override + public String convertToPresentation(String value, + Class<? extends String> targetType, Locale locale) + throws com.vaadin.data.util.converter.Converter.ConversionException { + return "presentation2"; + } + + @Override + public Class<String> getModelType() { + return String.class; + } + + @Override + public Class<String> getPresentationType() { + return String.class; + } + + }); + + initialProperties = table.getContainerPropertyIds(); + } + + private static Container createContainer(Object[] ids) { + Class[] types = new Class[ids.length]; + for (int i = 0; i < types.length; ++i) { + types[i] = String.class; + } + return createContainer(ids, types); + } + + private static Container createContainer(Object[] ids, Class[] types) { + IndexedContainer container = new IndexedContainer(); + if (ids.length > types.length) { + throw new IllegalArgumentException("Too few defined types"); + } + for (int i = 0; i < ids.length; ++i) { + container.addContainerProperty(ids[i], types[i], ""); + } + + for (int i = 0; i < 100; i++) { + Item item = container.addItem("item " + i); + for (int j = 0; j < ids.length; ++j) { + Property itemProperty = item.getItemProperty(ids[j]); + if (types[j] == String.class) { + itemProperty.setValue(ids[j].toString() + i); + } else if (types[j] == BaseClass.class) { + itemProperty.setValue(new BaseClass("base" + i)); + } else if (types[j] == DerivedClass.class) { + itemProperty.setValue(new DerivedClass("derived" + i)); + } else if (types[j] == int.class) { + // FIXME can't set values because the int is autoboxed into + // an Integer and not unboxed prior to set + + // itemProperty.setValue(i); + } else { + throw new IllegalArgumentException( + "Unhandled type in createContainer: " + types[j]); + } + } + } + + return container; + } + + private class TestableTable extends Table { + /** + * @param string + * @param createContainer + */ + public TestableTable(String string, Container container) { + super(string, container); + } + + Set<Object> getCurrentConverters() { + try { + Field f = Table.class + .getDeclaredField("propertyValueConverters"); + f.setAccessible(true); + HashMap<Object, Converter<String, Object>> pvc = (HashMap<Object, Converter<String, Object>>) f + .get(this); + Set<Object> currentConverters = new HashSet<Object>(); + for (Entry<Object, Converter<String, Object>> entry : pvc + .entrySet()) { + currentConverters.add(entry.getKey()); + } + return currentConverters; + + } catch (Exception e) { + fail("Unable to retrieve propertyValueConverters"); + return null; + } + } + } + + private static class BaseClass { + private String title; + + public BaseClass(String title) { + this.title = title; + } + } + + private static class DerivedClass extends BaseClass { + public DerivedClass(String title) { + super(title); + } + } +} diff --git a/shared/src/com/vaadin/shared/ui/label/ContentMode.java b/shared/src/com/vaadin/shared/ui/label/ContentMode.java index f71c6b0c75..37e821536d 100644 --- a/shared/src/com/vaadin/shared/ui/label/ContentMode.java +++ b/shared/src/com/vaadin/shared/ui/label/ContentMode.java @@ -27,7 +27,7 @@ public enum ContentMode { TEXT, /** - * Content mode, where the label contains pre formatted text. In this mode + * Content mode, where the label contains preformatted text. In this mode * newlines are preserved when rendered on the screen. */ PREFORMATTED, @@ -39,18 +39,18 @@ public enum ContentMode { /** * Content mode, where the label contains well-formed or well-balanced XML. - * This is handled in the same way as {@link #XHTML}. + * This is handled in the same way as {@link #HTML}. * - * @deprecated Use {@link #XHTML} instead + * @deprecated Use {@link #HTML} instead */ @Deprecated XML, /** * Legacy content mode, where the label contains RAW output. This is handled - * in exactly the same way as {@link #XHTML}. + * in exactly the same way as {@link #HTML}. * - * @deprecated Use {@link #XHTML} instead + * @deprecated Use {@link #HTML} instead */ @Deprecated RAW; diff --git a/shared/src/com/vaadin/shared/ui/ui/UIClientRpc.java b/shared/src/com/vaadin/shared/ui/ui/UIClientRpc.java index 3e0d292a06..5026189d71 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIClientRpc.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIClientRpc.java @@ -26,8 +26,11 @@ import com.vaadin.shared.communication.ClientRpc; public interface UIClientRpc extends ClientRpc { /** - * @since + * Informs the client that the UI has been closed + * * @param sessionExpired + * true if the ui was closed because the session expired, false + * otherwise */ void uiClosed(boolean sessionExpired); diff --git a/uitest/ivy.xml b/uitest/ivy.xml index ea22172937..f54ea7270e 100644 --- a/uitest/ivy.xml +++ b/uitest/ivy.xml @@ -93,7 +93,7 @@ <dependency org="org.hsqldb" name="hsqldb" rev="2.2.6" conf="build,ide -> default" /> <dependency org="com.vaadin" name="vaadin-testbench" - rev="3.1.3" conf="build-provided,ide -> default" /> + rev="4.0.0.alpha1" conf="build-provided,ide -> default" /> <!-- This should be removed once tests have been updated to use lang3 --> <dependency org="commons-lang" name="commons-lang" rev="2.6" conf="build,ide -> default" /> diff --git a/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTab.java b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTab.java new file mode 100644 index 0000000000..86e718596e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTab.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.accordion; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Accordion; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet.Tab; +import com.vaadin.ui.VerticalLayout; + +/** + * Test UI for Accordion: tabs should stay selectable after remove tab. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class AccordionRemoveTab extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Accordion tabs = new Accordion(); + addComponent(tabs); + tabs.setHeight(300, Unit.PIXELS); + final VerticalLayout one = new VerticalLayout(); + one.setCaption("One"); + one.addComponent(new Label("On first tab")); + tabs.addTab(one); + VerticalLayout two = new VerticalLayout(); + two.setCaption("Two"); + two.addComponent(new Label("On second tab")); + tabs.addTab(two); + + tabs.setSelectedTab(two); + + VerticalLayout l = new VerticalLayout(); + l.addComponent(new Label("On third tab")); + Tab last = tabs.addTab(l); + last.setCaption("Three"); + + Button remove = new Button("Remove First"); + remove.addClickListener(new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + tabs.removeComponent(tabs.iterator().next()); + } + }); + + addComponent(remove); + } + + @Override + protected String getTestDescription() { + return "Tabs should stay selectable after remove tab."; + } + + @Override + protected Integer getTicketNumber() { + return 11366; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java new file mode 100644 index 0000000000..f5651e0ada --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/accordion/AccordionRemoveTabTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.accordion; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for Accordion: tabs should stay selectable after remove tab. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class AccordionRemoveTabTest extends MultiBrowserTest { + + @Test + public void testRemoveTab() { + openTestURL(); + + WebElement button = driver.findElement(By.className("v-button")); + button.click(); + + checkFirstItemHeight("On second tab"); + + button.click(); + + checkFirstItemHeight("On third tab"); + } + + private void checkFirstItemHeight(String text) { + WebElement firstItem = driver.findElement(By + .className("v-accordion-item-first")); + WebElement label = firstItem.findElement(By.className("v-label")); + Assert.assertEquals("Unexpected text in first item", text, + label.getText()); + int height = firstItem.getSize().getHeight(); + WebElement accordion = driver.findElement(By.className("v-accordion")); + Assert.assertTrue("First item in accordion has unexpected height", + height > accordion.getSize().getHeight() / 2); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxItemAddingWithFocusListener.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxItemAddingWithFocusListener.java new file mode 100644 index 0000000000..8242eb9e57 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxItemAddingWithFocusListener.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import com.vaadin.event.FieldEvents.FocusEvent; +import com.vaadin.event.FieldEvents.FocusListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.ComboBox; + +/** + * Test UI to verify that focus event actually update the ComboBox suggestion + * popup + * + * @author Vaadin Ltd + */ +public class ComboBoxItemAddingWithFocusListener extends AbstractTestUI { + + private ComboBox cBox; + + @Override + protected void setup(VaadinRequest request) { + cBox = new ComboBox(); + addComponent(cBox); + cBox.setImmediate(true); + cBox.addItem("Foo"); + cBox.addItem("Bar"); + cBox.addFocusListener(new FocusListener() { + + int x = 0; + + @Override + public void focus(FocusEvent event) { + cBox.addItem("Focus" + (x++)); + } + + }); + addComponent(new Button("Focus Target")); + } + + @Override + protected String getTestDescription() { + return "Item adding in focus listener causes popup to clear"; + } + + @Override + protected Integer getTicketNumber() { + return 13635; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxItemAddingWithFocusListenerTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxItemAddingWithFocusListenerTest.java new file mode 100644 index 0000000000..66173db554 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxItemAddingWithFocusListenerTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.ComboBoxElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ComboBoxItemAddingWithFocusListenerTest extends MultiBrowserTest { + + @Test + public void testPopupViewContainsAddedItem() { + openTestURL(); + ComboBoxElement cBox = $(ComboBoxElement.class).first(); + ButtonElement focusTarget = $(ButtonElement.class).first(); + cBox.openPopup(); + int i = 0; + while (i < 3) { + assertTrue("No item added on focus", cBox.getPopupSuggestions() + .contains("Focus" + i++)); + focusTarget.focus(); + ((TestBenchElement) cBox.findElement(By.vaadin("#textbox"))) + .focus(); + } + assertTrue("No item added on focus", cBox.getPopupSuggestions() + .contains("Focus" + i)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldFastForward.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldFastForward.java new file mode 100644 index 0000000000..b38f58e5cc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldFastForward.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.datefield; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.InlineDateField; + +public class DateFieldFastForward extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + addComponent(new InlineDateField()); + } + + @Override + protected String getTestDescription() { + return "Tests that right-click doesn't interfere with fast-forwarding (holding down left mouse button)."; + } + + @Override + protected Integer getTicketNumber() { + return 8012; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldFastForwardTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldFastForwardTest.java new file mode 100644 index 0000000000..028160cc5d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldFastForwardTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.datefield; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldFastForwardTest extends MultiBrowserTest { + + @Test + public void testFastForwardOnRightMouseClick() throws Exception { + openTestURL(); + + WebElement nextMonthButton = driver.findElement(By + .className("v-button-nextmonth")); + + // Click and hold left mouse button to start fast forwarding. + new Actions(driver).clickAndHold(nextMonthButton).perform(); + Thread.sleep(1000); + + // Right click and release the left button. + new Actions(driver).contextClick(nextMonthButton) + .release(nextMonthButton).perform(); + + // Now the fast forwarding should be ended, get the expected month. + String expectedMonth = getSelectedMonth(); + + // Wait for a while. + Thread.sleep(1000); + + // Verify that we didn't fast forward any further after the left button + // was released. + String actualMonth = getSelectedMonth(); + assertEquals(expectedMonth, actualMonth); + } + + private String getSelectedMonth() { + return driver.findElement( + By.className("v-inline-datefield-calendarpanel-month")) + .getText(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayout.java b/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayout.java index 161314895c..49d88630a8 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayout.java +++ b/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayout.java @@ -35,7 +35,6 @@ public class DisabledParentLayout extends AbstractTestUI { content.setMargin(true); final VerticalLayout pane = new VerticalLayout(); - pane.setEnabled(false); pane.addComponent(new DateField()); content.addComponent(pane); @@ -44,7 +43,7 @@ public class DisabledParentLayout extends AbstractTestUI { button.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent event) { - pane.setEnabled(true); + pane.setEnabled(!pane.isEnabled()); } }); content.addComponent(button); diff --git a/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayoutTest.java b/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayoutTest.java index f1fdae834e..76486bf340 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayoutTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/DisabledParentLayoutTest.java @@ -35,17 +35,41 @@ public class DisabledParentLayoutTest extends MultiBrowserTest { WebElement button = driver.findElement(By.className("v-button")); button.click(); + WebElement textField = driver.findElement(By + .className("v-datefield-textfield")); + textField.click(); + + Assert.assertFalse( + "Date input text field shoud be disabled for disabled DateField", + textField.isEnabled()); + WebElement dataFieldButton = driver.findElement(By .className("v-datefield-button")); dataFieldButton.click(); - WebElement popup = driver - .findElement(By.className("v-datefield-popup")); + Assert.assertFalse( + "Disabled date popup is opened after click to its button", + isElementPresent(By.className("v-datefield-popup"))); + + button.click(); + + Assert.assertTrue( + "Date input text field shoud be enabled for enabled DateField", + textField.isEnabled()); + textField.click(); + String text = "text"; + textField.sendKeys(text); + + Assert.assertEquals("Unexpected text in date text field", text, + textField.getAttribute("value")); + + dataFieldButton.click(); Assert.assertFalse("Unexpected disabled element found", isElementPresent(By.className("v-disabled"))); - Assert.assertNotNull( - "Date popup is not opened after click to its button", popup); + Assert.assertTrue("Date popup is not opened after click to its button", + isElementPresent(By.className("v-datefield-popup"))); } + } diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropTextArea.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropTextArea.java new file mode 100644 index 0000000000..2ce3a42957 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropTextArea.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.draganddropwrapper; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.VerticalLayout; + +/** + * Test UI for text area: drag image should contain text-area text. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class DragAndDropTextArea extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout dndLayout = new VerticalLayout(); + + TextArea area = new TextArea(); + area.setValue("text"); + + dndLayout.addComponent(area); + DragAndDropWrapper wrapper = new DragAndDropWrapper(dndLayout); + wrapper.setDragStartMode(DragStartMode.WRAPPER); + addComponent(wrapper); + } + + @Override + protected String getTestDescription() { + return "Drag image for textarea should contain text-area text"; + } + + @Override + protected Integer getTicketNumber() { + return 13557; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropTextAreaTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropTextAreaTest.java new file mode 100644 index 0000000000..c60eead918 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragAndDropTextAreaTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.draganddropwrapper; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for drag image of text area which should contain text-area text. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class DragAndDropTextAreaTest extends MultiBrowserTest { + + @Test + public void testTextAreaDndImage() { + openTestURL(); + + WebElement wrapper = driver.findElement(By + .className("v-verticallayout")); + Actions actions = new Actions(driver); + actions.clickAndHold(wrapper); + actions.moveByOffset(50, 50); + actions.perform(); + + WebElement dragElement = driver.findElement(By + .className("v-drag-element")); + List<WebElement> children = dragElement.findElements(By.xpath(".//*")); + boolean found = false; + for (WebElement child : children) { + if ("text".equals(child.getAttribute("value"))) { + found = true; + } + } + + Assert.assertTrue( + "Text value is not found in the DnD image of text area", found); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModes.html b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModes.html deleted file mode 100644 index 3e7a7cb0a7..0000000000 --- a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModes.html +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>DragStartModes</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">DragStartModes</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.draganddropwrapper.DragStartModes?restartApplication</td> - <td></td> -</tr> -<tr> - <td>drag</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::PID_SlabelCOMPONENT</td> - <td>50,10</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> - <td>50,10</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>drag-mode-component</td> -</tr> -<tr> - <td>drop</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> - <td>50,10</td> -</tr> -<tr> - <td>drag</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::PID_SlabelWRAPPER</td> - <td>50,10</td> -</tr> -<tr> - <td>mouseMoveAt</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> - <td>50,10</td> -</tr> -<tr> - <td>screenCapture</td> - <td></td> - <td>drag-mode-wrapper</td> -</tr> -<tr> - <td>drop</td> - <td>vaadin=runcomvaadintestscomponentsdraganddropwrapperDragStartModes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td> - <td>50,10</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java new file mode 100644 index 0000000000..25aef1b815 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/draganddropwrapper/DragStartModesTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.draganddropwrapper; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DragStartModesTest extends MultiBrowserTest { + + @Test + public void testDragStartModes() throws IOException { + openTestURL(); + WebElement dropTarget = vaadinElement("/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]"); + dragToTarget("COMPONENT", dropTarget); + dragToTarget("WRAPPER", dropTarget); + } + + private void dragToTarget(String dragMode, WebElement dropTarget) + throws IOException { + WebElement draggable = vaadinElementById("label" + dragMode); + new Actions(driver).moveToElement(draggable, 10, 10).clickAndHold() + .moveByOffset(5, 0).perform(); + new Actions(driver).moveToElement(dropTarget, 12, 10).perform(); + compareScreen("dragMode" + dragMode); + new Actions(driver).release().perform(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutScrollPosition.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutScrollPosition.java new file mode 100644 index 0000000000..9bc29b5c82 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutScrollPosition.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.gridlayout; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; + +public class GridLayoutScrollPosition extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + + Panel panel = new Panel(); + setContent(panel); + + GridLayout gridLayout = new GridLayout(); + gridLayout.setWidth("500px"); + panel.setContent(gridLayout); + gridLayout.setColumns(1); + gridLayout.setRows(1); + + Label dummyLabel = new Label("Dummy"); + dummyLabel.setHeight("500px"); + gridLayout.addComponent(dummyLabel); + + final CheckBox visibilityToggleCheckBox = new CheckBox( + "Hide / Show toggleable components"); + visibilityToggleCheckBox.setId("visibility-toggle"); + visibilityToggleCheckBox.setHeight("2000px"); + visibilityToggleCheckBox.setImmediate(true); + visibilityToggleCheckBox.setValue(false); // Initially unchecked + gridLayout.addComponent(visibilityToggleCheckBox); + + final Label toggleableLabel = new Label("Toggleable Label"); + toggleableLabel.setHeight("2000px"); + toggleableLabel.setVisible(false); // Initially hidden + gridLayout.addComponent(toggleableLabel); + + visibilityToggleCheckBox + .addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + toggleableLabel.setVisible(visibilityToggleCheckBox + .getValue()); + } + }); + + } + + @Override + protected String getTestDescription() { + return "The UI scroll position should not be reset when visibility of GridLayout children is toggled"; + } + + @Override + protected Integer getTicketNumber() { + return 13386; + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutScrollPositionTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutScrollPositionTest.java new file mode 100644 index 0000000000..961b08002b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutScrollPositionTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.gridlayout; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridLayoutScrollPositionTest extends MultiBrowserTest { + + @Test + public void testToggleChildComponents() throws Exception { + + final int SCROLLTOP = 100; + + openTestURL(); + + WebDriver driver = getDriver(); + + WebElement ui = driver.findElement(By.className("v-ui")); + + testBenchElement(ui).scroll(SCROLLTOP); + + driver.findElement(By.id("visibility-toggle")) + .findElement(By.tagName("input")).click(); + + assertEquals("UI scroll position", String.valueOf(SCROLLTOP), + ui.getAttribute("scrollTop")); + } +} diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewWithExtension.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewWithExtension.java new file mode 100644 index 0000000000..04bbf6df0a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewWithExtension.java @@ -0,0 +1,55 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.popupview; + +import com.vaadin.server.Responsive; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; +import com.vaadin.ui.PopupView; + +/** + * Test UI for popup view with extension: extension is a part of getChildren() + * collection but is not inside the getChildComponents() collection. Popup view + * should use getChildComponents() to avoid exception when extension is returned + * by getChildren(). + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class PopupViewWithExtension extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Label label = new Label("label"); + PopupView view = new PopupView("small", label); + + Responsive.makeResponsive(view); + + addComponent(view); + } + + @Override + protected String getTestDescription() { + return "PopupView should use getChildComponents() in the connector, not getChildren()"; + } + + @Override + protected Integer getTicketNumber() { + return 13503; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewWithExtensionTest.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewWithExtensionTest.java new file mode 100644 index 0000000000..4d11190ea9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewWithExtensionTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.popupview; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Popup view with extension should not throw an exception. + * + * @since 7.2 + * @author Vaadin Ltd + */ +public class PopupViewWithExtensionTest extends MultiBrowserTest { + + @Test + public void testPopupView() { + setDebug(true); + openTestURL(); + + WebElement view = driver.findElement(By.className("v-popupview")); + view.click(); + + Assert.assertFalse( + "Popup view with extension should not throw an exception. " + + "(Error notification window is shown).", + isElementPresent(By.className("v-Notification-error"))); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/DndEmptyTable.java b/uitest/src/com/vaadin/tests/components/table/DndEmptyTable.java new file mode 100644 index 0000000000..baac7ce057 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/DndEmptyTable.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import com.vaadin.event.dd.DragAndDropEvent; +import com.vaadin.event.dd.DropHandler; +import com.vaadin.event.dd.acceptcriteria.AcceptAll; +import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.Label; +import com.vaadin.ui.Table; + +/** + * Test UI for empty table: empty table (without any data) throws client side + * exception if it's a target for DnD. + * + * @since + * @author Vaadin Ltd + */ +public class DndEmptyTable extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Label source = new Label("label"); + DragAndDropWrapper wrapper = new DragAndDropWrapper(source); + wrapper.setDragStartMode(DragStartMode.WRAPPER); + addComponent(wrapper); + + Table target = new Table(); + target.setWidth(100, Unit.PERCENTAGE); + addComponent(target); + target.setDropHandler(new DropHandler() { + + @Override + public AcceptCriterion getAcceptCriterion() { + return AcceptAll.get(); + } + + @Override + public void drop(DragAndDropEvent event) { + } + }); + } + + @Override + protected String getTestDescription() { + return "Drag and drop into empty table should not throws client side exception."; + } + + @Override + protected Integer getTicketNumber() { + return 13655; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/DndEmptyTableTest.java b/uitest/src/com/vaadin/tests/components/table/DndEmptyTableTest.java new file mode 100644 index 0000000000..4c682637b1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/DndEmptyTableTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for empty table as a DnD target: it should not throws client side + * exception. + * + * @since + * @author Vaadin Ltd + */ +public class DndEmptyTableTest extends MultiBrowserTest { + + @Test + public void testDndEmptyTable() { + setDebug(true); + openTestURL(); + + WebElement source = driver.findElement(By.className("v-ddwrapper")); + WebElement target = driver.findElement(By.className("v-table-body")); + Actions actions = new Actions(driver); + actions.clickAndHold(source).moveToElement(target).release(); + + Assert.assertFalse(isElementPresent(By + .className("v-Notification-error"))); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/LeftColumnAlignment.java b/uitest/src/com/vaadin/tests/components/table/LeftColumnAlignment.java new file mode 100644 index 0000000000..e783951d86 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/LeftColumnAlignment.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import com.vaadin.annotations.Theme; +import com.vaadin.data.util.BeanItemContainer; +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.Table; +import com.vaadin.ui.Table.Align; + +/** + * Test UI for issue #13399 : Left alignment should not be set explicitly + * instead of relying on default behavior + * + * @author Vaadin Ltd + */ +@Theme("tests-table") +public class LeftColumnAlignment extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Table table = new Table(); + + BeanItemContainer<Bean> container = new BeanItemContainer<Bean>( + Bean.class); + Bean bean = new Bean(); + bean.setName("property"); + container.addBean(bean); + table.setContainerDataSource(container); + + table.setFooterVisible(true); + + table.setWidth(100, Unit.PIXELS); + + table.setColumnAlignment("name", Align.RIGHT); + + addComponent(table); + + Button button = new Button("Align to Left"); + button.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + table.setColumnAlignment("name", Align.LEFT); + } + }); + addComponent(button); + } + + @Override + protected String getTestDescription() { + return "Left alignment should not be set explicitly instead of relying on default behavior"; + } + + @Override + protected Integer getTicketNumber() { + return 13399; + } + + public static class Bean { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/LeftColumnAlignmentTest.java b/uitest/src/com/vaadin/tests/components/table/LeftColumnAlignmentTest.java new file mode 100644 index 0000000000..3d613fd726 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/LeftColumnAlignmentTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test class for issue #13399 : Left alignment should not be set explicitly + * instead of relying on default behavior + * + * @author Vaadin Ltd + */ +public class LeftColumnAlignmentTest extends MultiBrowserTest { + + @Test + public void testLeftColumnAlignment() throws Exception { + openTestURL(); + + // Do align columns to the left + WebElement webElement = driver.findElement(By.className("v-button")); + webElement.click(); + + Assert.assertTrue("Table caption is not aligned to the left", + isElementPresent(By + .className("v-table-caption-container-align-left"))); + + WebElement footer = driver.findElement(By + .className("v-table-footer-container")); + + Assert.assertEquals("Table footer is not aligned to the left", "left", + footer.getCssValue("text-align")); + + WebElement cell = driver.findElement(By + .className("v-table-cell-wrapper")); + + Assert.assertEquals("Table cell is not aligned to the left", "left", + cell.getCssValue("text-align")); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableSortingIndicator.java b/uitest/src/com/vaadin/tests/components/table/TableSortingIndicator.java new file mode 100644 index 0000000000..93fe8d7d9e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableSortingIndicator.java @@ -0,0 +1,129 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import java.util.Random; + +import com.vaadin.data.Container; +import com.vaadin.data.util.BeanItemContainer; +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.Table; + +/** + * Test if the table sorting indicators update correctly when the table is + * sorted serverside + * + * @author Vaadin Ltd + */ +public class TableSortingIndicator extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + final Table table = new Table("Test table", buildContainer()); + table.setSizeFull(); + addComponent(table); + Button sortButton = new Button("Sort", new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + table.sort(new Object[] { "val1" }, new boolean[] { false }); + } + }); + addComponent(sortButton); + } + + private Container buildContainer() { + BeanItemContainer<TestBean> container = new BeanItemContainer<TestBean>( + TestBean.class); + for (int i = 0; i < 100; ++i) { + TestBean item = new TestBean(); + item.setVal1(i); + item.setVal2(randomWord()); + item.setVal3(randomWord()); + container.addBean(item); + } + return container; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "The table should have visible sorting indicators."; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 8978; + } + + public class TestBean { + private Integer val1; + private String val2; + private String val3; + + public Integer getVal1() { + return val1; + } + + public void setVal1(Integer val1) { + this.val1 = val1; + } + + public String getVal2() { + return val2; + } + + public void setVal2(String val2) { + this.val2 = val2; + } + + public String getVal3() { + return val3; + } + + public void setVal3(String val3) { + this.val3 = val3; + } + } + + private String randomWord() { + Random rng = new Random(); + char[] word = new char[3 + rng.nextInt(10)]; + for (int i = 0; i < word.length; ++i) { + word[i] = (char) ('a' + rng.nextInt(26)); + } + return new String(word); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableSortingIndicatorTest.java b/uitest/src/com/vaadin/tests/components/table/TableSortingIndicatorTest.java new file mode 100644 index 0000000000..36a51b35e3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableSortingIndicatorTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests if the sort indicator is visible after the table has been sorted from + * the serverside. + * + * @author Vaadin Ltd + */ +public class TableSortingIndicatorTest extends MultiBrowserTest { + private static final String TABLE_HEADER_DESC_INDICATOR = "v-table-header-cell-desc"; + private static final String TABLE_HEADER_ASC_INDICATOR = "v-table-header-cell-asc"; + + @Test + public void testTableSortingIndicatorIsVisibleAfterServersideSort() { + openTestURL(); + + Assert.assertFalse("Descending indicator was prematurely visible", + isElementPresent(By.className(TABLE_HEADER_DESC_INDICATOR))); + Assert.assertFalse("Ascending indicator was prematurely visible", + isElementPresent(By.className(TABLE_HEADER_ASC_INDICATOR))); + WebElement button = driver.findElement(By + .vaadin("//Button[caption=\"Sort\"]")); + button.click(); + Assert.assertTrue("Indicator did not become visible", + isElementPresent(By.className(TABLE_HEADER_DESC_INDICATOR))); + + Assert.assertFalse("Ascending sort indicator was wrongly visible", + isElementPresent(By.className(TABLE_HEADER_ASC_INDICATOR))); + WebElement manualSort = driver.findElement(By + .className(TABLE_HEADER_DESC_INDICATOR)); + manualSort.click(); + Assert.assertFalse("Table sort indicator didn't change", + isElementPresent(By.className(TABLE_HEADER_DESC_INDICATOR))); + Assert.assertTrue("Ascending sort indicator didn't become visible", + isElementPresent(By.className(TABLE_HEADER_ASC_INDICATOR))); + button.click(); + Assert.assertTrue( + "Descending sort indicator didn't appear on the second serverside sort.", + isElementPresent(By.className(TABLE_HEADER_DESC_INDICATOR))); + Assert.assertFalse("Ascending sort indicator didn't disappear", + isElementPresent(By.className(TABLE_HEADER_ASC_INDICATOR))); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableWidthItemRemove.java b/uitest/src/com/vaadin/tests/components/table/TableWidthItemRemove.java new file mode 100644 index 0000000000..79a85cd49b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableWidthItemRemove.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +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.Table; + +/** + * Test whether adding the first item to a table calculates the table width + * correctly + * + * @author Vaadin Ltd + */ +public class TableWidthItemRemove extends AbstractTestUI { + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + final Table table = new Table("My table"); + table.addContainerProperty("firstName", String.class, null); + table.addContainerProperty("lastName", String.class, null); + table.addContainerProperty("year", Integer.class, null); + table.setColumnWidth("firstName", 200); + table.setColumnWidth("lastName", 100); + table.setColumnWidth("year", 50); + + Button cleanButton = new Button("Clean"); + cleanButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + table.removeAllItems(); + } + }); + addComponent(cleanButton); + + Button populateButton = new Button("Populate"); + populateButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + table.addItem( + new Object[] { "John", "Doe", new Integer(1980) }, + Math.random() * 1000); + } + }); + addComponent(populateButton); + + addComponent(table); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "The table should retain the correct width on item remove and add."; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 13592; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/TableWidthItemRemoveTest.java b/uitest/src/com/vaadin/tests/components/table/TableWidthItemRemoveTest.java new file mode 100644 index 0000000000..f96641be4c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/TableWidthItemRemoveTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.table; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test whether adding the first item to a table calculates the table width + * correctly + * + * @author Vaadin Ltd + */ +public class TableWidthItemRemoveTest extends MultiBrowserTest { + @Test + public void testWidthResizeOnItemAdd() { + openTestURL(); + + WebElement populateButton = driver.findElement(By + .vaadin("//Button[caption=\"Populate\"]")); + WebElement table = driver.findElement(By + .vaadin("//Table[caption=\"My table\"]")); + int original_width = table.getSize().getWidth(); + populateButton.click(); + Assert.assertTrue("Width changed on item add.", original_width == table + .getSize().getWidth()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxPageLengthZeroScroll.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxPageLengthZeroScroll.java new file mode 100644 index 0000000000..82c04191d1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxPageLengthZeroScroll.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.ComboBox; + +/** + * Test UI for issue #13488, where scrolling to the next page with pagelength 0 + * would break the rendering of any page except the first. + * + * @author Vaadin Ltd + */ +@SuppressWarnings("serial") +public class ComboboxPageLengthZeroScroll extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + ComboBox combobox = new ComboBox("New items enabled:"); + combobox.setPageLength(0); + + for (int i = 0; i++ < 10;) { + combobox.addItem("1 AMERICAN SAMOA " + i); + combobox.addItem("ANTIGUA AND BARBUDA " + i); + } + + getLayout().addComponent(combobox); + getLayout().addComponent(new Button("dummy")); + } + + @Override + protected String getTestDescription() { + return "Scrolling with pagelength == 0 previously resulted in broken style, should be fixed now"; + } + + @Override + protected Integer getTicketNumber() { + return 13488; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxPageLengthZeroScrollTest.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxPageLengthZeroScrollTest.java new file mode 100644 index 0000000000..eecf83417e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxPageLengthZeroScrollTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test class for testing issue #13488 - changing pages with pagelength=0 breaks + * the style. + * + * @author Vaadin Ltd + */ + +public class ComboboxPageLengthZeroScrollTest extends MultiBrowserTest { + @Test + public void testComboboxPageLength() { + openTestURL(); + + WebElement comboBox = vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#textbox"); + + // navigate to the next page. keyboard navigation is the preferred + // method here since it's much easier to implement. + + Actions keyNavigation = new Actions(driver).moveToElement(comboBox) + .click(); + + for (int i = 0; i < 25; ++i) { + keyNavigation.sendKeys(Keys.ARROW_DOWN); + + } + keyNavigation.perform(); + + // The broken behavior always caused a v-shadow element to have + // height: 10px. Verify that this does no longer happen. + + String cssValue = driver.findElement(By.className("v-shadow")) + .getCssValue("height"); + + Assert.assertNotEquals("v-shadow height should not be 10px", "10px", + cssValue); + + } +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagation.java b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagation.java new file mode 100644 index 0000000000..31eeac02da --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagation.java @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import com.vaadin.event.ShortcutAction.KeyCode; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextArea; +import com.vaadin.ui.TextField; + +/** + * UI test for TextArea behavior when ENTER has been assigned as a keyboard + * shortcut. + * + * @author Vaadin Ltd + */ +public class TextAreaEventPropagation extends AbstractTestUIWithLog { + + protected static final String BUTTON_PRESSED = "Button Pressed"; + + protected static final String NO_BUTTON_PRESSED = "No Button Pressed"; + + private Label enterButtonPressed; + + private Label escapeButtonPressed; + + @Override + protected void setup(VaadinRequest request) { + + FormLayout form = new FormLayout(); + TextArea textArea = new TextArea("Text input"); + TextField textField = new TextField("Text field input"); + enterButtonPressed = new Label("Enter Label"); + enterButtonPressed.setCaption(NO_BUTTON_PRESSED); + escapeButtonPressed = new Label("Escape Label"); + escapeButtonPressed.setCaption(NO_BUTTON_PRESSED); + + Button enterButton = new Button("Enter"); + enterButton.setClickShortcut(KeyCode.ENTER); + enterButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + + enterButtonPressed.setCaption(BUTTON_PRESSED); + } + }); + + Button escapeButton = new Button("Escape"); + escapeButton.setClickShortcut(KeyCode.ESCAPE); + escapeButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + + escapeButtonPressed.setCaption(BUTTON_PRESSED); + } + }); + + form.addComponent(textArea); + form.addComponent(textField); + form.addComponent(enterButton); + form.addComponent(escapeButton); + form.addComponent(enterButtonPressed); + form.addComponent(escapeButtonPressed); + addComponent(form); + + } + + @Override + protected String getTestDescription() { + return "Currently if enter key is set as a shortcut for some component, it won't be possible for the user to enter newline in a textarea."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(12424); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationTest.java b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationTest.java new file mode 100644 index 0000000000..11e0c52d27 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that the TextArea widget correctly stops ENTER events from propagating. + * + * @author Vaadin Ltd + */ +public class TextAreaEventPropagationTest extends MultiBrowserTest { + + @Test + public void testTextAreaEnterEventPropagation() throws InterruptedException { + openTestURL(); + WebElement textArea = vaadinElement("//TextArea[0]"); + Actions builder = new Actions(driver); + builder.click(textArea); + builder.sendKeys(textArea, "first line asdf"); + builder.sendKeys(Keys.ENTER); + builder.sendKeys(textArea, "second line jkl;"); + builder.perform(); + + WebElement enterLabel = driver.findElement(By.id("gwt-uid-8")); + String text = enterLabel.getText(); + assertEquals(TextAreaEventPropagation.NO_BUTTON_PRESSED, text); + + WebElement textField = vaadinElement("//TextField[0]"); + Actions builder2 = new Actions(driver); + builder2.click(textField); + + builder2.sendKeys("third line"); + builder2.sendKeys(Keys.ENTER); + + builder2.perform(); + + text = enterLabel.getText(); + + assertEquals(TextAreaEventPropagation.BUTTON_PRESSED, text); + + } + + @Test + public void testTextAreaEscapeEventPropagation() + throws InterruptedException { + openTestURL(); + WebElement textArea = vaadinElement("//TextArea[0]"); + Actions builder = new Actions(driver); + builder.click(textArea); + builder.sendKeys(textArea, "first line asdf"); + builder.sendKeys(Keys.ENTER); + builder.sendKeys(textArea, "second line jkl;"); + builder.sendKeys(Keys.ESCAPE); + builder.perform(); + + WebElement enterLabel = driver.findElement(By.id("gwt-uid-8")); + String text = enterLabel.getText(); + assertEquals(TextAreaEventPropagation.NO_BUTTON_PRESSED, text); + WebElement escapeLabel = driver.findElement(By.id("gwt-uid-10")); + text = escapeLabel.getText(); + assertEquals(TextAreaEventPropagation.BUTTON_PRESSED, text); + + } + + @Test + public void testTextFieldEscapeEventPropagation() + throws InterruptedException { + openTestURL(); + WebElement textArea = vaadinElement("//TextArea[0]"); + Actions builder = new Actions(driver); + builder.click(textArea); + builder.sendKeys(textArea, "first line asdf"); + builder.sendKeys(Keys.ENTER); + builder.sendKeys(textArea, "second line jkl;"); + builder.perform(); + + WebElement enterLabel = driver.findElement(By.id("gwt-uid-8")); + String text = enterLabel.getText(); + assertEquals(TextAreaEventPropagation.NO_BUTTON_PRESSED, text); + WebElement escapeLabel = driver.findElement(By.id("gwt-uid-10")); + + WebElement textField = vaadinElement("//TextField[0]"); + Actions builder2 = new Actions(driver); + builder2.click(textField); + + builder2.sendKeys("third line"); + builder2.sendKeys(Keys.ENTER); + builder2.sendKeys(Keys.ESCAPE); + + builder2.perform(); + + text = enterLabel.getText(); + assertEquals(TextAreaEventPropagation.BUTTON_PRESSED, text); + + text = escapeLabel.getText(); + + assertEquals(TextAreaEventPropagation.BUTTON_PRESSED, text); + + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java index 14d82ab1fb..b5440b8f76 100644 --- a/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java +++ b/uitest/src/com/vaadin/tests/components/ui/TimeoutRedirectResetsOnActivityTest.java @@ -19,6 +19,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.openqa.selenium.WebElement; @@ -39,6 +40,7 @@ public class TimeoutRedirectResetsOnActivityTest extends MultiBrowserTest { private static int i = 0; @Test + @Ignore("The test modifies the system messages, which are global and the changes will affect other tests") public void verifyRedirectWorks() throws Exception { setDebug(true); openTestURL(); diff --git a/uitest/src/com/vaadin/tests/resources/CachingJavaScriptComponent.java b/uitest/src/com/vaadin/tests/resources/CachingJavaScriptComponent.java new file mode 100644 index 0000000000..b6e409d4ba --- /dev/null +++ b/uitest/src/com/vaadin/tests/resources/CachingJavaScriptComponent.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.resources; + +import com.vaadin.annotations.JavaScript; +import com.vaadin.ui.AbstractJavaScriptComponent; + +@JavaScript({ "cachingtest.js" }) +public class CachingJavaScriptComponent extends AbstractJavaScriptComponent { + public CachingJavaScriptComponent() { + + } +} diff --git a/uitest/src/com/vaadin/tests/resources/PublishedFileHandlerCaching.java b/uitest/src/com/vaadin/tests/resources/PublishedFileHandlerCaching.java new file mode 100644 index 0000000000..a2828032c7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/resources/PublishedFileHandlerCaching.java @@ -0,0 +1,77 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.resources; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; + +/** + * This class tests the caching behavior of PublishedFileHandler. + * + * Previously PublishedFileHandler did not include cache headers in it's + * responses. Unfortunately there isn't a good way to automate this test, so + * manual testing is required at this time. To test the caching behavior run + * this file as a java application on the development server debug + * configuration, and access it through the url + * http://localhost:8888/run/com.vaadin + * .tests.resources.PublishedFileHandlerCaching?restartApplication + * + * On loading the page you'll need to examine the network traffic (e.g. with + * FireBug), keeping an eye on the GET requests for cachingtest.js and it's + * cache headers. + * + * @since + * @author Vaadin Ltd + */ +public class PublishedFileHandlerCaching extends AbstractTestUI { + + /** + * generated serialVersionUID + */ + private static final long serialVersionUID = 2275457343547688505L; + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + addComponent(new CachingJavaScriptComponent()); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Test that PublishedFileHandler includes appropriate cache headers."; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return new Integer(13574); + } + +} diff --git a/uitest/src/com/vaadin/tests/resources/cachingtest.js b/uitest/src/com/vaadin/tests/resources/cachingtest.js new file mode 100644 index 0000000000..f948e680ad --- /dev/null +++ b/uitest/src/com/vaadin/tests/resources/cachingtest.js @@ -0,0 +1,6 @@ +/** + * Used for testing cache header behavior. + */ + +function com_vaadin_tests_resources_CachingJavaScriptComponent() { +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index 10a520d7a4..fd3131cbbf 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -765,6 +765,21 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } /** + * Gets the capabilities for PhantomJS of the given version + * + * @param version + * the major version + * @return an object describing the capabilities required for running a + * test on the given PhantomJS version + */ + public static DesiredCapabilities phantomJS(int version) { + DesiredCapabilities c = DesiredCapabilities.phantomjs(); + c.setPlatform(Platform.XP); + c.setVersion("" + version); + return c; + } + + /** * Checks if the given capabilities refer to Internet Explorer 8 * * @param capabilities @@ -821,6 +836,15 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } /** + * @param capabilities + * The capabilities to check + * @return true if the capabilities refer to PhantomJS, false otherwise + */ + public static boolean isPhantomJS(DesiredCapabilities capabilities) { + return BrowserType.PHANTOMJS.equals(capabilities.getBrowserName()); + } + + /** * Returns a human readable identifier of the given browser. Used for * test naming and screenshots * @@ -839,6 +863,8 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { return "Safari"; } else if (isOpera(capabilities)) { return "Opera"; + } else if (isPhantomJS(capabilities)) { + return "PhantomJS"; } return capabilities.getBrowserName(); diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java index 9e3fd38950..13c34d475a 100644 --- a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java +++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java @@ -44,7 +44,7 @@ public abstract class MultiBrowserTest extends PrivateTB3Configuration { FIREFOX(BrowserUtil.firefox(24)), CHROME(BrowserUtil.chrome(33)), SAFARI( BrowserUtil.safari(7)), IE8(BrowserUtil.ie(8)), IE9(BrowserUtil .ie(9)), IE10(BrowserUtil.ie(10)), IE11(BrowserUtil.ie(11)), OPERA( - BrowserUtil.opera(17)); + BrowserUtil.opera(17)), PHANTOMJS(BrowserUtil.phantomJS(1)); private DesiredCapabilities desiredCapabilities; private Browser(DesiredCapabilities desiredCapabilities) { |