Browse Source

Merge branch 'master-before-18503' into grid-unbuffered-editor

Conflicts:
	server/src/com/vaadin/data/RpcDataProviderExtension.java
	uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java

Change-Id: I9e7907c9caf839fd043444db0505f9853f020a6a
tags/7.6.0.alpha4
Henri Sara 8 years ago
parent
commit
123c9fbc74
69 changed files with 1698 additions and 179 deletions
  1. 1
    0
      WebContent/VAADIN/themes/tests-tickets/folder with space/resource with special $chars@.txt
  2. 1
    0
      WebContent/VAADIN/themes/tests-tickets/ordinary.txt
  3. 1
    0
      WebContent/VAADIN/themes/tests-tickets/percentagein%20name.txt
  4. 5
    0
      WebContent/VAADIN/themes/valo/components/_grid.scss
  5. 16
    0
      client/src/com/vaadin/client/BrowserInfo.java
  6. 54
    3
      client/src/com/vaadin/client/ComputedStyle.java
  7. 4
    4
      client/src/com/vaadin/client/ResourceLoader.java
  8. 22
    3
      client/src/com/vaadin/client/connectors/GridConnector.java
  9. 1
    1
      client/src/com/vaadin/client/ui/FocusableScrollPanel.java
  10. 22
    4
      client/src/com/vaadin/client/ui/VFilterSelect.java
  11. 0
    17
      client/src/com/vaadin/client/ui/VFormLayout.java
  12. 1
    13
      client/src/com/vaadin/client/ui/VOverlay.java
  13. 1
    1
      client/src/com/vaadin/client/ui/VRichTextArea.java
  14. 9
    5
      client/src/com/vaadin/client/ui/VScrollTable.java
  15. 8
    2
      client/src/com/vaadin/client/ui/VTabsheet.java
  16. 4
    4
      client/src/com/vaadin/client/ui/VTextArea.java
  17. 1
    9
      client/src/com/vaadin/client/ui/VUI.java
  18. 12
    17
      client/src/com/vaadin/client/ui/VWindow.java
  19. 7
    2
      client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java
  20. 5
    2
      client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java
  21. 14
    0
      client/src/com/vaadin/client/ui/ui/UIConnector.java
  22. 9
    5
      client/src/com/vaadin/client/ui/window/WindowConnector.java
  23. 4
    0
      client/src/com/vaadin/client/widget/grid/selection/MultiSelectionRenderer.java
  24. 43
    6
      client/src/com/vaadin/client/widgets/Escalator.java
  25. 65
    37
      client/src/com/vaadin/client/widgets/Grid.java
  26. 25
    0
      client/tests/src/com/vaadin/client/VBrowserDetailsUserAgentParserTest.java
  27. 1
    1
      eclipse/Super Development Mode (vaadin).launch
  28. 37
    0
      scripts/DeployHelpers.py
  29. 53
    0
      scripts/GeneratePublishReport.py
  30. 39
    2
      scripts/GenerateStagingReport.py
  31. 1
    1
      server/ivy.xml
  32. 12
    8
      server/src/com/vaadin/server/VaadinServlet.java
  33. 14
    0
      server/src/com/vaadin/server/WebBrowser.java
  34. 7
    0
      server/src/com/vaadin/server/communication/AtmospherePushConnection.java
  35. 1
    1
      server/src/com/vaadin/server/communication/FileUploadHandler.java
  36. 29
    1
      server/src/com/vaadin/ui/Grid.java
  37. 7
    0
      server/src/com/vaadin/ui/HorizontalLayout.java
  38. 7
    0
      server/src/com/vaadin/ui/VerticalLayout.java
  39. 1
    1
      server/src/com/vaadin/ui/renderers/ImageRenderer.java
  40. 103
    17
      server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java
  41. 25
    0
      shared/src/com/vaadin/shared/VBrowserDetails.java
  42. 11
    0
      shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java
  43. 2
    1
      uitest/integration_tests.xml
  44. 1
    1
      uitest/ivy.xml
  45. 1
    1
      uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java
  46. 12
    2
      uitest/src/com/vaadin/tests/components/calendar/NullEventMoveHandler.java
  47. 15
    0
      uitest/src/com/vaadin/tests/components/calendar/NullEventMoveHandlerTest.java
  48. 40
    0
      uitest/src/com/vaadin/tests/components/combobox/ComboboxPopupScrolling.java
  49. 60
    0
      uitest/src/com/vaadin/tests/components/combobox/ComboboxPopupScrollingTest.java
  50. 40
    0
      uitest/src/com/vaadin/tests/components/combobox/CustomComboBoxElement.java
  51. 0
    5
      uitest/src/com/vaadin/tests/components/grid/GridDetailsLocationTest.java
  52. 43
    0
      uitest/src/com/vaadin/tests/components/grid/GridWithBrokenRenderer.java
  53. 41
    0
      uitest/src/com/vaadin/tests/components/grid/GridWithBrokenRendererTest.java
  54. 20
    0
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java
  55. 2
    0
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java
  56. 58
    0
      uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java
  57. 43
    0
      uitest/src/com/vaadin/tests/components/tabsheet/TabSheetInSplitPanel.java
  58. 43
    0
      uitest/src/com/vaadin/tests/components/tabsheet/TabSheetInSplitPanelTest.java
  59. 51
    0
      uitest/src/com/vaadin/tests/components/treetable/TreeTableScrollOnExpand.java
  60. 46
    0
      uitest/src/com/vaadin/tests/components/treetable/TreeTableScrollOnExpandTest.java
  61. 49
    0
      uitest/src/com/vaadin/tests/components/window/GridInWindow.java
  62. 36
    0
      uitest/src/com/vaadin/tests/components/window/GridInWindowTest.java
  63. 62
    0
      uitest/src/com/vaadin/tests/components/window/OpenModalWindowAndFocusField.java
  64. 48
    0
      uitest/src/com/vaadin/tests/components/window/OpenModalWindowAndFocusFieldTest.java
  65. 94
    0
      uitest/src/com/vaadin/tests/push/ManualLongPollingPushUI.java
  66. 54
    0
      uitest/src/com/vaadin/tests/push/ManualLongPollingPushUITest.java
  67. 52
    0
      uitest/src/com/vaadin/tests/resources/SpecialCharsInThemeResources.java
  68. 92
    2
      uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
  69. 10
    0
      uitest/src/com/vaadin/tests/tb3/newelements/WindowElement.java

+ 1
- 0
WebContent/VAADIN/themes/tests-tickets/folder with space/resource with special $chars@.txt View File

@@ -0,0 +1 @@
Just ordinary contents here

+ 1
- 0
WebContent/VAADIN/themes/tests-tickets/ordinary.txt View File

@@ -0,0 +1 @@
Just ordinary contents here

+ 1
- 0
WebContent/VAADIN/themes/tests-tickets/percentagein%20name.txt View File

@@ -0,0 +1 @@
Just ordinary contents here

+ 5
- 0
WebContent/VAADIN/themes/valo/components/_grid.scss View File

@@ -21,6 +21,11 @@ $v-grid-details-marker-width: first-number($v-grid-border) * 2 !default;
$v-grid-details-marker-color: $v-selection-color !default;
$v-grid-details-border-top: valo-border($color: $v-grid-border-color-source, $strength: 0.3) !default;
$v-grid-details-border-top-stripe: valo-border($color: $v-grid-row-stripe-background-color, $strength: 0.3) !default;

$v-grid-border-size: 1px !default;
$v-grid-border: $v-grid-border-size solid #ddd !default;
$v-grid-cell-vertical-border: $v-grid-border !default;
$v-grid-cell-horizontal-border: $v-grid-cell-vertical-border !default;
$v-grid-details-border-bottom: $v-grid-cell-horizontal-border !default;
$v-grid-details-border-bottom-stripe: $v-grid-cell-horizontal-border !default;


+ 16
- 0
client/src/com/vaadin/client/BrowserInfo.java View File

@@ -30,6 +30,7 @@ public class BrowserInfo {

private static final String BROWSER_OPERA = "op";
private static final String BROWSER_IE = "ie";
private static final String BROWSER_EDGE = "edge";
private static final String BROWSER_FIREFOX = "ff";
private static final String BROWSER_SAFARI = "sa";

@@ -171,6 +172,13 @@ public class BrowserInfo {
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = ENGINE_TRIDENT;
} else if (browserDetails.isEdge()) {
browserIdentifier = BROWSER_EDGE;
majorVersionClass = browserIdentifier
+ getBrowserMajorVersion();
minorVersionClass = majorVersionClass
+ browserDetails.getBrowserMinorVersion();
browserEngineClass = "";
} else if (browserDetails.isOpera()) {
browserIdentifier = BROWSER_OPERA;
majorVersionClass = browserIdentifier
@@ -225,6 +233,10 @@ public class BrowserInfo {
return browserDetails.isIE();
}

public boolean isEdge() {
return browserDetails.isEdge();
}

public boolean isFirefox() {
return browserDetails.isFirefox();
}
@@ -245,6 +257,10 @@ public class BrowserInfo {
return isIE() && getBrowserMajorVersion() == 10;
}

public boolean isIE11() {
return isIE() && getBrowserMajorVersion() == 11;
}

public boolean isChrome() {
return browserDetails.isChrome();
}

+ 54
- 3
client/src/com/vaadin/client/ComputedStyle.java View File

@@ -155,10 +155,10 @@ public class ComputedStyle {
* the property to retrieve
* @return the double value of the property
*/
public final int getDoubleProperty(String name) {
public final double getDoubleProperty(String name) {
Profiler.enter("ComputedStyle.getDoubleProperty");
String value = getProperty(name);
int result = parseDoubleNative(value);
double result = parseDoubleNative(value);
Profiler.leave("ComputedStyle.getDoubleProperty");
return result;
}
@@ -275,9 +275,60 @@ public class ComputedStyle {
* @return the value from the string before any non-numeric characters or
* NaN if the value cannot be parsed as a number
*/
private static native int parseDoubleNative(final String value)
private static native double parseDoubleNative(final String value)
/*-{
return parseFloat(value);
}-*/;

/**
* Returns the sum of the top and bottom border width
*
* @since 7.5.3
* @return the sum of the top and bottom border
*/
public double getBorderHeight() {
double borderHeight = getDoubleProperty("borderTopWidth");
borderHeight += getDoubleProperty("borderBottomWidth");

return borderHeight;
}

/**
* Returns the sum of the left and right border width
*
* @since 7.5.3
* @return the sum of the left and right border
*/
public double getBorderWidth() {
double borderWidth = getDoubleProperty("borderLeftWidth");
borderWidth += getDoubleProperty("borderRightWidth");

return borderWidth;
}

/**
* Returns the sum of the top and bottom padding
*
* @since 7.5.3
* @return the sum of the top and bottom padding
*/
public double getPaddingHeight() {
double paddingHeight = getDoubleProperty("paddingTop");
paddingHeight += getDoubleProperty("paddingBottom");

return paddingHeight;
}

/**
* Returns the sum of the top and bottom padding
*
* @since 7.5.3
* @return the sum of the left and right padding
*/
public double getPaddingWidth() {
double paddingWidth = getDoubleProperty("paddingLeft");
paddingWidth += getDoubleProperty("paddingRight");

return paddingWidth;
}
}

+ 4
- 4
client/src/com/vaadin/client/ResourceLoader.java View File

@@ -283,8 +283,7 @@ public class ResourceLoader {
* @since 7.2.4
*/
public static boolean supportsInOrderScriptExecution() {
return BrowserInfo.get().isIE()
&& BrowserInfo.get().getBrowserMajorVersion() >= 11;
return BrowserInfo.get().isIE11() || BrowserInfo.get().isEdge();
}

/**
@@ -486,10 +485,11 @@ public class ResourceLoader {
addOnloadHandler(linkElement, new ResourceLoadListener() {
@Override
public void onLoad(ResourceLoadEvent event) {
// Chrome && IE fires load for errors, must check
// Chrome, IE, Edge all fire load for errors, must check
// stylesheet data
if (BrowserInfo.get().isChrome()
|| BrowserInfo.get().isIE()) {
|| BrowserInfo.get().isIE()
|| BrowserInfo.get().isEdge()) {
int styleSheetLength = getStyleSheetLength(url);
// Error if there's an empty stylesheet
if (styleSheetLength == 0) {

+ 22
- 3
client/src/com/vaadin/client/connectors/GridConnector.java View File

@@ -34,6 +34,7 @@ import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ConnectorHierarchyChangeEvent;
@@ -476,8 +477,7 @@ public class GridConnector extends AbstractHasComponentsConnector implements
/**
* Class for handling scrolling issues with open details.
*
* @since
* @author Vaadin Ltd
* @since 7.5.2
*/
private class LazyDetailsScroller implements DeferredWorker {

@@ -507,7 +507,6 @@ public class GridConnector extends AbstractHasComponentsConnector implements
/**
* Inform LazyDetailsScroller that a details row has opened on a row.
*
* @since
* @param rowIndex
* index of row with details now open
*/
@@ -685,6 +684,26 @@ public class GridConnector extends AbstractHasComponentsConnector implements
public void recalculateColumnWidths() {
getWidget().recalculateColumnWidths();
}

@Override
public void setSelectAll(boolean allSelected) {
if (selectionModel instanceof SelectionModel.Multi
&& selectionModel.getSelectionColumnRenderer() != null) {
final Widget widget;
try {
HeaderRow defaultHeaderRow = getWidget()
.getDefaultHeaderRow();
if (defaultHeaderRow != null) {
widget = defaultHeaderRow.getCell(
getWidget().getColumn(0)).getWidget();
((CheckBox) widget).setValue(allSelected, false);
}
} catch (Exception e) {
getLogger().warning(
"Problems finding select all checkbox.");
}
}
}
});

getWidget().addSelectionHandler(internalSelectionChangeHandler);

+ 1
- 1
client/src/com/vaadin/client/ui/FocusableScrollPanel.java View File

@@ -74,7 +74,7 @@ public class FocusableScrollPanel extends SimpleFocusablePanel implements
style.setPosition(Position.FIXED);
style.setTop(0, Unit.PX);
style.setLeft(0, Unit.PX);
if (browserInfo.isIE()) {
if (browserInfo.isIE() || browserInfo.isEdge()) {
// for #15294: artificially hide little bit more the
// focusElement, otherwise IE will make the window to scroll
// into it when focused

+ 22
- 4
client/src/com/vaadin/client/ui/VFilterSelect.java View File

@@ -599,7 +599,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
+ "]");

Element menuFirstChild = menu.getElement().getFirstChildElement();
final int naturalMenuWidth = menuFirstChild.getOffsetWidth();
final int naturalMenuWidth = WidgetUtil
.getRequiredWidth(menuFirstChild);

if (popupOuterPadding == -1) {
popupOuterPadding = WidgetUtil
@@ -611,13 +612,20 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
menuFirstChild.getStyle().setWidth(100, Unit.PCT);
}

if (BrowserInfo.get().isIE()) {
if (BrowserInfo.get().isIE()
&& BrowserInfo.get().getBrowserMajorVersion() < 11) {
// Must take margin,border,padding manually into account for
// menu element as we measure the element child and set width to
// the element parent
int naturalMenuOuterWidth = naturalMenuWidth
+ getMarginBorderPaddingWidth(menu.getElement());

/*
* IE requires us to specify the width for the container
* element. Otherwise it will be 100% wide
*/
int rootWidth = Math.max(desiredWidth, naturalMenuWidth)
- popupOuterPadding;
int rootWidth = Math.max(desiredWidth - popupOuterPadding,
naturalMenuOuterWidth);
getContainerElement().getStyle().setWidth(rootWidth, Unit.PX);
}

@@ -1283,6 +1291,16 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler,
sinkEvents(Event.ONPASTE);
}

private static int getMarginBorderPaddingWidth(Element element) {
final ComputedStyle s = new ComputedStyle(element);
int[] margin = s.getMargin();
int[] border = s.getBorder();
int[] padding = s.getPadding();
return margin[1] + margin[3] + border[1] + border[3] + padding[1]
+ padding[3];

}

/*
* (non-Javadoc)
*

+ 0
- 17
client/src/com/vaadin/client/ui/VFormLayout.java View File

@@ -22,7 +22,6 @@ import java.util.List;

import com.google.gwt.aria.client.Roles;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
@@ -327,22 +326,6 @@ public class VFormLayout extends SimplePanel {
requiredFieldIndicator = null;
}
}

// Workaround for IE weirdness, sometimes returns bad height in some
// circumstances when Caption is empty. See #1444
// IE7 bugs more often. I wonder what happens when IE8 arrives...
// FIXME: This could be unnecessary for IE8+
if (BrowserInfo.get().isIE()) {
if (isEmpty) {
setHeight("0px");
getElement().getStyle().setOverflow(Overflow.HIDDEN);
} else {
setHeight("");
getElement().getStyle().clearOverflow();
}

}

}

/**

+ 1
- 13
client/src/com/vaadin/client/ui/VOverlay.java View File

@@ -22,8 +22,6 @@ import java.util.logging.Logger;
import com.google.gwt.animation.client.Animation;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.IFrameElement;
@@ -473,17 +471,7 @@ public class VOverlay extends PopupPanel implements CloseHandler<PopupPanel> {
if (isAnimationEnabled()) {
new ResizeAnimation().run(POPUP_PANEL_ANIMATION_DURATION);
} else {
if (BrowserInfo.get().isIE8()) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {

@Override
public void execute() {
positionOrSizeUpdated(1.0);
}
});
} else {
positionOrSizeUpdated(1.0);
}
positionOrSizeUpdated(1.0);
}
current = null;
}

+ 1
- 1
client/src/com/vaadin/client/ui/VRichTextArea.java View File

@@ -322,7 +322,7 @@ public class VRichTextArea extends Composite implements Field, KeyPressHandler,
if ("<br>".equals(result)) {
result = "";
}
} else if (browser.isWebkit()) {
} else if (browser.isWebkit() || browser.isEdge()) {
if ("<br>".equals(result) || "<div><br></div>".equals(result)) {
result = "";
}

+ 9
- 5
client/src/com/vaadin/client/ui/VScrollTable.java View File

@@ -1295,8 +1295,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (uidl.hasVariable("selected")) {
final Set<String> selectedKeys = uidl
.getStringArrayVariableAsSet("selected");
removeUnselectedRowKeys(selectedKeys);

// Do not update focus if there is a single selected row
// that is the same as the previous selection. This prevents
// unwanted scrolling (#18247).
boolean rowsUnSelected = removeUnselectedRowKeys(selectedKeys);
boolean updateFocus = rowsUnSelected || selectedRowKeys.size() == 0
|| focusedRow == null;
if (scrollBody != null) {
Iterator<Widget> iterator = scrollBody.iterator();
while (iterator.hasNext()) {
@@ -1313,7 +1317,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
selected = true;
keyboardSelectionOverRowFetchInProgress = true;
}
if (selected && selectedKeys.size() == 1) {
if (selected && selectedKeys.size() == 1 && updateFocus) {
/*
* If a single item is selected, move focus to the
* selected row. (#10522)
@@ -1338,14 +1342,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return keyboardSelectionOverRowFetchInProgress;
}

private void removeUnselectedRowKeys(final Set<String> selectedKeys) {
private boolean removeUnselectedRowKeys(final Set<String> selectedKeys) {
List<String> unselectedKeys = new ArrayList<String>(0);
for (String key : selectedRowKeys) {
if (!selectedKeys.contains(key)) {
unselectedKeys.add(key);
}
}
selectedRowKeys.removeAll(unselectedKeys);
return selectedRowKeys.removeAll(unselectedKeys);
}

/** For internal use only. May be removed or replaced in the future. */

+ 8
- 2
client/src/com/vaadin/client/ui/VTabsheet.java View File

@@ -61,11 +61,12 @@ import com.google.gwt.user.client.ui.impl.FocusImpl;
import com.vaadin.client.ApplicationConnection;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ComputedStyle;
import com.vaadin.client.Focusable;
import com.vaadin.client.TooltipInfo;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.VCaption;
import com.vaadin.client.VTooltip;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.ui.aria.AriaHelper;
import com.vaadin.shared.AbstractComponentState;
import com.vaadin.shared.ComponentConstants;
@@ -1227,8 +1228,13 @@ public class VTabsheet extends VTabsheetBase implements Focusable, SubPartAware
public void updateContentNodeHeight() {
if (!isDynamicHeight()) {
int contentHeight = getOffsetHeight();
contentHeight -= DOM.getElementPropertyInt(deco, "offsetHeight");
contentHeight -= deco.getOffsetHeight();
contentHeight -= tb.getOffsetHeight();

ComputedStyle cs = new ComputedStyle(contentNode);
contentHeight -= Math.ceil(cs.getPaddingHeight());
contentHeight -= Math.ceil(cs.getBorderHeight());

if (contentHeight < 0) {
contentHeight = 0;
}

+ 4
- 4
client/src/com/vaadin/client/ui/VTextArea.java View File

@@ -224,16 +224,16 @@ public class VTextArea extends VTextField implements DragImageModifier {

protected boolean browserSupportsMaxLengthAttribute() {
BrowserInfo info = BrowserInfo.get();
if (info.isFirefox() && info.isBrowserVersionNewerOrEqual(4, 0)) {
if (info.isFirefox()) {
return true;
}
if (info.isSafari() && info.isBrowserVersionNewerOrEqual(5, 0)) {
if (info.isSafari()) {
return true;
}
if (info.isIE() && info.isBrowserVersionNewerOrEqual(10, 0)) {
if (info.isIE10() || info.isIE11() || info.isEdge()) {
return true;
}
if (info.isAndroid() && info.isBrowserVersionNewerOrEqual(2, 3)) {
if (info.isAndroid()) {
return true;
}
return false;

+ 1
- 9
client/src/com/vaadin/client/ui/VUI.java View File

@@ -18,7 +18,6 @@ package com.vaadin.client.ui;

import java.util.ArrayList;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.HasScrollHandlers;
@@ -44,8 +43,8 @@ import com.vaadin.client.ConnectorMap;
import com.vaadin.client.Focusable;
import com.vaadin.client.LayoutManager;
import com.vaadin.client.Profiler;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.VConsole;
import com.vaadin.client.WidgetUtil;
import com.vaadin.client.ui.ShortcutActionHandler.ShortcutActionHandlerOwner;
import com.vaadin.client.ui.TouchScrollDelegate.TouchScrollHandler;
import com.vaadin.client.ui.ui.UIConnector;
@@ -515,13 +514,6 @@ public class VUI extends SimplePanel implements ResizeHandler,
public void focusStoredElement() {
if (storedFocus != null) {
storedFocus.focus();

Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
storedFocus.focus();
}
});
}
}


+ 12
- 17
client/src/com/vaadin/client/ui/VWindow.java View File

@@ -562,17 +562,10 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,
}

private static void focusTopmostModalWindow() {
// If we call focus() directly without scheduling, it does not work in
// IE and FF.
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
VWindow topmost = getTopmostWindow();
if ((topmost != null) && (topmost.vaadinModality)) {
topmost.focus();
}
}
});
VWindow topmost = getTopmostWindow();
if ((topmost != null) && (topmost.vaadinModality)) {
topmost.focus();
}
}

@Override
@@ -762,11 +755,9 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,

modalityCurtain.removeFromParent();

if (BrowserInfo.get().isIE()) {
// IE leaks memory in certain cases unless we release the reference
// (#9197)
modalityCurtain = null;
}
// IE leaks memory in certain cases unless we release the reference
// (#9197)
modalityCurtain = null;
}

/*
@@ -1375,7 +1366,11 @@ public class VWindow extends VOverlay implements ShortcutActionHandlerOwner,

@Override
public void focus() {
contentPanel.focus();
// We don't want to use contentPanel.focus() as that will use a timer in
// Chrome/Safari and ultimately run focus events in the wrong order when
// opening a modal window and focusing some other component at the same
// time
contentPanel.getElement().focus();
}

private int getDecorationHeight() {

+ 7
- 2
client/src/com/vaadin/client/ui/calendar/schedule/DateCellDayEvent.java View File

@@ -268,8 +268,13 @@ public class DateCellDayEvent extends FocusableHTML implements
}
int endX = event.getClientX();
int endY = event.getClientY();
int xDiff = startX - endX;
int yDiff = startY - endY;
int xDiff = 0, yDiff = 0;
if (startX != -1 && startY != -1) {
// Drag started
xDiff = startX - endX;
yDiff = startY - endY;
}

startX = -1;
startY = -1;
mouseMoveStarted = false;

+ 5
- 2
client/src/com/vaadin/client/ui/calendar/schedule/SimpleDayCell.java View File

@@ -392,8 +392,11 @@ public class SimpleDayCell extends FocusableFlowPanel implements

int endX = event.getClientX();
int endY = event.getClientY();
int xDiff = startX - endX;
int yDiff = startY - endY;
int xDiff = 0, yDiff = 0;
if (startX != -1 && startY != -1) {
xDiff = startX - endX;
yDiff = startY - endY;
}
startX = -1;
startY = -1;
prevDayDiff = 0;

+ 14
- 0
client/src/com/vaadin/client/ui/ui/UIConnector.java View File

@@ -72,6 +72,7 @@ import com.vaadin.client.ui.ShortcutActionHandler;
import com.vaadin.client.ui.VNotification;
import com.vaadin.client.ui.VOverlay;
import com.vaadin.client.ui.VUI;
import com.vaadin.client.ui.VWindow;
import com.vaadin.client.ui.layout.MayScrollChildren;
import com.vaadin.client.ui.window.WindowConnector;
import com.vaadin.server.Page.Styles;
@@ -677,6 +678,19 @@ public class UIConnector extends AbstractSingleComponentContainerConnector
if (c instanceof WindowConnector) {
WindowConnector wc = (WindowConnector) c;
wc.setWindowOrderAndPosition();
VWindow window = wc.getWidget();
if (!window.isAttached()) {

// Attach so that all widgets inside the Window are attached
// when their onStateChange is run

// Made invisible here for legacy reasons and made visible
// at the end of stateChange. This dance could probably be
// removed
window.setVisible(false);
window.show();
}

}
}


+ 9
- 5
client/src/com/vaadin/client/ui/window/WindowConnector.java View File

@@ -17,6 +17,8 @@ package com.vaadin.client.ui.window;

import java.util.logging.Logger;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Node;
@@ -354,10 +356,6 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
if (state.modal != window.vaadinModality) {
window.setVaadinModality(!window.vaadinModality);
}
if (!window.isAttached()) {
window.setVisible(false); // hide until possible centering
window.show();
}
boolean resizeable = state.resizable
&& state.windowMode == WindowMode.NORMAL;
window.setResizable(resizeable);
@@ -407,7 +405,13 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector
window.centered = state.centered;
// Ensure centering before setting visible (#16486)
if (window.centered && getState().windowMode != WindowMode.MAXIMIZED) {
window.center();
Scheduler.get().scheduleFinally(new ScheduledCommand() {

@Override
public void execute() {
getWidget().center();
}
});
}
window.setVisible(true);


+ 4
- 0
client/src/com/vaadin/client/widget/grid/selection/MultiSelectionRenderer.java View File

@@ -56,6 +56,8 @@ import com.vaadin.client.widgets.Grid;
public class MultiSelectionRenderer<T> extends
ClickableRenderer<Boolean, CheckBox> {

private static final String SELECTION_CHECKBOX_CLASSNAME = "-selection-checkbox";

/** The size of the autoscroll area, both top and bottom. */
private static final int SCROLL_AREA_GRADIENT_PX = 100;

@@ -591,6 +593,8 @@ public class MultiSelectionRenderer<T> extends
@Override
public CheckBox createWidget() {
final CheckBox checkBox = GWT.create(CheckBox.class);
checkBox.setStylePrimaryName(grid.getStylePrimaryName()
+ SELECTION_CHECKBOX_CLASSNAME);
CheckBoxEventHandler handler = new CheckBoxEventHandler(checkBox);

// Sink events

+ 43
- 6
client/src/com/vaadin/client/widgets/Escalator.java View File

@@ -1475,6 +1475,9 @@ public class Escalator extends Widget implements RequiresResize,
cellElem.addClassName("frozen");
position.set(cellElem, scroller.lastScrollLeft, 0);
}
if (columnConfiguration.frozenColumns > 0 && col == columnConfiguration.frozenColumns - 1) {
cellElem.addClassName("last-frozen");
}
}

referenceRow = paintInsertRow(referenceRow, tr, row);
@@ -1732,6 +1735,14 @@ public class Escalator extends Widget implements RequiresResize,
}

public void setColumnFrozen(int column, boolean frozen) {
toggleFrozenColumnClass(column, frozen, "frozen");

if (frozen) {
updateFreezePosition(column, scroller.lastScrollLeft);
}
}

private void toggleFrozenColumnClass(int column, boolean frozen, String className) {
final NodeList<TableRowElement> childRows = root.getRows();

for (int row = 0; row < childRows.getLength(); row++) {
@@ -1742,16 +1753,16 @@ public class Escalator extends Widget implements RequiresResize,

TableCellElement cell = tr.getCells().getItem(column);
if (frozen) {
cell.addClassName("frozen");
cell.addClassName(className);
} else {
cell.removeClassName("frozen");
cell.removeClassName(className);
position.reset(cell);
}
}
}

if (frozen) {
updateFreezePosition(column, scroller.lastScrollLeft);
}
public void setColumnLastFrozen(int column, boolean lastFrozen) {
toggleFrozenColumnClass(column, lastFrozen, "last-frozen");
}

public void updateFreezePosition(int column, double scrollLeft) {
@@ -4309,6 +4320,17 @@ public class Escalator extends Widget implements RequiresResize,
firstUnaffectedCol = oldCount;
}

if (oldCount > 0) {
header.setColumnLastFrozen(oldCount - 1, false);
body.setColumnLastFrozen(oldCount - 1, false);
footer.setColumnLastFrozen(oldCount - 1, false);
}
if (count > 0) {
header.setColumnLastFrozen(count - 1, true);
body.setColumnLastFrozen(count - 1, true);
footer.setColumnLastFrozen(count - 1, true);
}

for (int col = firstAffectedCol; col < firstUnaffectedCol; col++) {
header.setColumnFrozen(col, frozen);
body.setColumnFrozen(col, frozen);
@@ -5619,14 +5641,29 @@ public class Escalator extends Widget implements RequiresResize,
horizontalScrollbar.setScrollbarThickness(scrollbarThickness);
horizontalScrollbar
.addVisibilityHandler(new ScrollbarBundle.VisibilityHandler() {

private boolean queued = false;

@Override
public void visibilityChanged(
ScrollbarBundle.VisibilityChangeEvent event) {
if (queued) {
return;
}
queued = true;

/*
* We either lost or gained a scrollbar. In any case, we
* need to change the height, if it's defined by rows.
*/
applyHeightByRows();
Scheduler.get().scheduleFinally(new ScheduledCommand() {

@Override
public void execute() {
applyHeightByRows();
queued = false;
}
});
}
});


+ 65
- 37
client/src/com/vaadin/client/widgets/Grid.java View File

@@ -216,6 +216,8 @@ public class Grid<T> extends ResizeComposite implements
HasSelectionHandlers<T>, SubPartAware, DeferredWorker, Focusable,
com.google.gwt.user.client.ui.Focusable, HasWidgets, HasEnabled {

private static final String SELECT_ALL_CHECKBOX_CLASSNAME = "-select-all-checkbox";

/**
* Enum describing different sections of Grid.
*/
@@ -2535,6 +2537,7 @@ public class Grid<T> extends ResizeComposite implements

private boolean initDone = false;
private boolean selected = false;
private CheckBox selectAllCheckBox;

SelectionColumn(final Renderer<Boolean> selectColumnRenderer) {
super(selectColumnRenderer);
@@ -2559,41 +2562,57 @@ public class Grid<T> extends ResizeComposite implements
* exist.
*/
final SelectionModel.Multi<T> model = (Multi<T>) getSelectionModel();
final CheckBox checkBox = GWT.create(CheckBox.class);
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {

@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
if (event.getValue()) {
fireEvent(new SelectAllEvent<T>(model));
selected = true;
} else {
model.deselectAll();
selected = false;
}
}
});
checkBox.setValue(selected);
selectionCell.setWidget(checkBox);
// Select all with space when "select all" cell is active
addHeaderKeyUpHandler(new HeaderKeyUpHandler() {
@Override
public void onKeyUp(GridKeyUpEvent event) {
if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE) {
return;
}
HeaderRow targetHeaderRow = getHeader().getRow(
event.getFocusedCell().getRowIndex());
if (!targetHeaderRow.isDefault()) {
return;
if (selectAllCheckBox == null) {
selectAllCheckBox = GWT.create(CheckBox.class);
selectAllCheckBox.setStylePrimaryName(getStylePrimaryName()
+ SELECT_ALL_CHECKBOX_CLASSNAME);
selectAllCheckBox
.addValueChangeHandler(new ValueChangeHandler<Boolean>() {

@Override
public void onValueChange(
ValueChangeEvent<Boolean> event) {
if (event.getValue()) {
fireEvent(new SelectAllEvent<T>(model));
selected = true;
} else {
model.deselectAll();
selected = false;
}
}
});
selectAllCheckBox.setValue(selected);

// Select all with space when "select all" cell is active
addHeaderKeyUpHandler(new HeaderKeyUpHandler() {
@Override
public void onKeyUp(GridKeyUpEvent event) {
if (event.getNativeKeyCode() != KeyCodes.KEY_SPACE) {
return;
}
HeaderRow targetHeaderRow = getHeader().getRow(
event.getFocusedCell().getRowIndex());
if (!targetHeaderRow.isDefault()) {
return;
}
if (event.getFocusedCell().getColumn() == SelectionColumn.this) {
// Send events to ensure state is updated
selectAllCheckBox.setValue(
!selectAllCheckBox.getValue(), true);
}
}
if (event.getFocusedCell().getColumn() == SelectionColumn.this) {
// Send events to ensure row selection state is
// updated
checkBox.setValue(!checkBox.getValue(), true);
});
} else {
for (HeaderRow row : header.getRows()) {
if (row.getCell(this).getType() == GridStaticCellType.WIDGET) {
// Detach from old header.
row.getCell(this).setText("");
}
}
});
}

selectionCell.setWidget(selectAllCheckBox);
}

@Override
@@ -2655,7 +2674,6 @@ public class Grid<T> extends ResizeComposite implements
super.setEditable(editable);
return this;
}

}

/**
@@ -6927,11 +6945,21 @@ public class Grid<T> extends ResizeComposite implements

if (args.getIndicesLength() == 0) {
return editor.editorOverlay;
} else if (args.getIndicesLength() == 1
&& args.getIndex(0) < columns.size()) {
escalator
.scrollToColumn(args.getIndex(0), ScrollDestination.ANY, 0);
return editor.getWidget(columns.get(args.getIndex(0))).getElement();
} else if (args.getIndicesLength() == 1) {
int index = args.getIndex(0);
if (index >= columns.size()) {
return null;
}

escalator.scrollToColumn(index, ScrollDestination.ANY, 0);
Widget widget = editor.getWidget(columns.get(index));

if (widget != null) {
return widget.getElement();
}

// No widget for the column.
return null;
}

return null;

+ 25
- 0
client/tests/src/com/vaadin/client/VBrowserDetailsUserAgentParserTest.java View File

@@ -56,6 +56,8 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
private static final String ANDROID_MOTOROLA_3_0 = "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13";
private static final String ANDROID_GALAXY_NEXUS_4_0_4_CHROME = "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19";

private static final String EDGE_WINDOWS_10 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240";

public void testSafari3() {
VBrowserDetails bd = new VBrowserDetails(SAFARI3_WINDOWS);
assertWebKit(bd);
@@ -423,6 +425,14 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
assertWindows(bd, true);
}

public void testEdgeWindows10() {
VBrowserDetails bd = new VBrowserDetails(EDGE_WINDOWS_10);
assertEdge(bd);
assertBrowserMajorVersion(bd, 12);
assertBrowserMinorVersion(bd, 10240);
assertWindows(bd, false);
}

/*
* Helper methods below
*/
@@ -484,6 +494,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
assertFalse(browserDetails.isIE());
assertFalse(browserDetails.isOpera());
assertFalse(browserDetails.isSafari());
assertFalse(browserDetails.isEdge());
}

private void assertChrome(VBrowserDetails browserDetails) {
@@ -493,6 +504,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
assertFalse(browserDetails.isIE());
assertFalse(browserDetails.isOpera());
assertFalse(browserDetails.isSafari());
assertFalse(browserDetails.isEdge());
}

private void assertIE(VBrowserDetails browserDetails) {
@@ -502,6 +514,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
assertTrue(browserDetails.isIE());
assertFalse(browserDetails.isOpera());
assertFalse(browserDetails.isSafari());
assertFalse(browserDetails.isEdge());
}

private void assertOpera(VBrowserDetails browserDetails) {
@@ -511,6 +524,7 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
assertFalse(browserDetails.isIE());
assertTrue(browserDetails.isOpera());
assertFalse(browserDetails.isSafari());
assertFalse(browserDetails.isEdge());
}

private void assertSafari(VBrowserDetails browserDetails) {
@@ -520,6 +534,17 @@ public class VBrowserDetailsUserAgentParserTest extends TestCase {
assertFalse(browserDetails.isIE());
assertFalse(browserDetails.isOpera());
assertTrue(browserDetails.isSafari());
assertFalse(browserDetails.isEdge());
}

private void assertEdge(VBrowserDetails browserDetails) {
// Browser
assertFalse(browserDetails.isFirefox());
assertFalse(browserDetails.isChrome());
assertFalse(browserDetails.isIE());
assertFalse(browserDetails.isOpera());
assertFalse(browserDetails.isSafari());
assertTrue(browserDetails.isEdge());
}

private void assertMacOSX(VBrowserDetails browserDetails) {

+ 1
- 1
eclipse/Super Development Mode (vaadin).launch View File

@@ -23,5 +23,5 @@
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.codeserver.CodeServer"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-noprecompile -strict -bindAddress 0.0.0.0 com.vaadin.DefaultWidgetSet com.vaadin.tests.widgetset.TestingWidgetSet"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="vaadin"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx512M -XX:MaxPermSize=256M"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx1G -XX:MaxPermSize=256M"/>
</launchConfiguration>

+ 37
- 0
scripts/DeployHelpers.py View File

@@ -12,14 +12,51 @@ except Exception as e:
from requests.auth import HTTPDigestAuth
from os.path import join, expanduser, basename
from BuildHelpers import parser, getArgs
from time import sleep

parser.add_argument("--deployUrl", help="Wildfly management URL")
parser.add_argument("--deployUser", help="Deployment user", default=None)
parser.add_argument("--deployPass", help="Deployment password", default=None)

serverUp = None

def testServer():
global serverUp

if serverUp is not None:
return serverUp

print("Checking server status")
i = 0
request = {"operation" : "read-attribute", "name" : "server-state"}
serverUp = False
while not serverUp and i < 2:
try:
print("Trying on url %s" % (getUrl()))
result = doPostJson(url=getUrl(), auth=getAuth(), data=json.dumps(request))
response = result.json()
if "outcome" not in response or response["outcome"] != "success":
# Failure
raise Exception(response)
elif "result" not in response or response["result"] != "running":
# Another failure
raise Exception(response)
# All OK
serverUp = True
print("Got server connection.")
except Exception as e:
print("Exception while checking server state: ", e)
print("Server connection failed, retrying in 5 seconds.")
i = i + 1
sleep(5)
return serverUp

# Helper for handling the full deployment
# name should end with .war
def deployWar(warFile, name=None):
if not testServer():
raise Exception("Server not up. Skipping deployment.")
return
if name is None:
name = basename(warFile).replace('.war', "-%s.war" % (getArgs().version.split('-')[0]))


+ 53
- 0
scripts/GeneratePublishReport.py View File

@@ -0,0 +1,53 @@
#coding=UTF-8

import argparse, cgi

parser = argparse.ArgumentParser(description="Post-publish report generator")
parser.add_argument("version", type=str, help="Vaadin version that was just built")
parser.add_argument("buildResultUrl", type=str, help="URL for the build result page")

args = parser.parse_args()

(major, minor, maintenance) = args.version.split(".", 2)
prerelease = "." in maintenance
if prerelease:
maintenance = maintenance.split('.')[0]

content = """<html>
<head></head>
<body>
<table>
"""

if not prerelease:
content += "<tr><td><a href='http://vaadin.com/download/release/{maj}.{min}/{ver}/'>Check {ver} is published to vaadin.com/download</td></tr>".format(maj=major, min=minor, ver=args.version)
else:
content += "<tr><td><a href='http://vaadin.com/download/prerelease/{maj}.{min}/{maj}.{min}.{main}/{ver}'>Check {ver} is published as prerelease to vaadin.com/download</td></tr>".format(maj=major, min=minor, main=maintenance, ver=args.version)

content += """
<tr><td>Verify Latest Vaadin 7: <iframe src="http://vaadin.com/download/LATEST7"></iframe></td></tr>
<tr><td>Verify Vaadin 7 Version List: <iframe src="http://vaadin.com/download/VERSIONS_7"></iframe></td></tr>
<tr><td>Verify Latest Vaadin 7.5: <iframe src="http://vaadin.com/download/release/7.5/LATEST"></iframe></td></tr>
<tr><td>Verify Latest Vaadin 7.6: <iframe src="http://vaadin.com/download/release/7.6/LATEST"></iframe></td></tr>
<tr><td>Verify Latest Vaadin 6: <iframe src="http://vaadin.com/download/LATEST"></iframe></td></tr>
<tr><td>Verify Latest Vaadin 7 Prerelease: <iframe src="http://vaadin.com/download/PRERELEASES"></iframe></td></tr>"""

if not prerelease:
content += '<tr><td><a href="https://dev.vaadin.com/admin/ticket/versions">Set latest version to default</a></td></tr>'

content += """
<tr><td><a href="http://test.vaadin.com/{version}/run/LabelModes?restartApplication">Verify uploaded to test.vaadin.com</a></td></tr>
<tr><td><a href="https://github.com/vaadin/vaadin/tags">Verify tags pushed to GitHub</a></td></tr>""".format(version=args.version)

if not prerelease:
content += '<tr><td><a href="http://vaadin.com/api">Verify API version list updated</a></td></tr>'

content += """
<tr><td><a href="https://dev.vaadin.com/query?status=pending-release&component=Core+Framework&resolution=fixed&milestone=Vaadin {version}&col=id&col=summary&col=component&col=milestone&col=status&col=type">Batch update tickets in Trac</a></td></tr>
<tr><td><a href="{url}">Publish result page (See test results, pin and tag build and dependencies)</a></td></tr>
</table>
</body>
</html>""".format(url=args.buildResultUrl, version=args.version)

f = open("result/report.html", 'w')
f.write(content)

+ 39
- 2
scripts/GenerateStagingReport.py View File

@@ -9,6 +9,7 @@ parser.add_argument("version", type=str, help="Vaadin version that was just buil
parser.add_argument("deployUrl", type=str, help="Base url of the deployment server")
parser.add_argument("buildResultUrl", type=str, help="URL for the build result page")
parser.add_argument("stagingRepo", type=str, help="URL for the staging repository")
parser.add_argument("tbapiUrl", type=str, help="URL for the TestBench API build")

args = parser.parse_args()

@@ -35,12 +36,48 @@ content += cgi.escape(""" <ibiblio name="vaadin-staging" usepoms="true" m2compat
root="{repoUrl}" />""".format(repoUrl=args.stagingRepo))
content += """</pre>
</td></tr>
<tr><td><a href="https://dev.vaadin.com/milestone/Vaadin {version}">Trac Milestone</a></td></tr>
<tr><td><a href="https://dev.vaadin.com/milestone/Vaadin {version}">Close Trac Milestone</a></td></tr>
<tr><td><a href="https://dev.vaadin.com/query?status=pending-release&component=Core+Framework&resolution=fixed&col=id&col=summary&col=component&col=milestone&col=status&col=type">Verify pending release tickets still have milestone {version}</a></td></tr>
<tr><td><a href="https://dev.vaadin.com/admin/ticket/versions">Add version {version} to Trac</td></tr>
<tr><td><a href="{url}">Staging result page (See test results, pin and tag build and dependencies)</a></td></tr>
<tr><td>Commands to tag all repositories (warning: do not run as a single script but set variables and check before any push commands - this has not been tested yet and the change IDs are missing)</td></tr>
<tr><td><pre>
VERSION={version}

GERRIT_USER=[fill in your gerrit username]
FRAMEWORK_REVISION=[fill in framework revision]
SCREENSHOTS_REVISION=[fill in screenshot repository revision]
ARCHETYPES_REVISION=[fill in maven-integration repository revision]
PLUGIN_REVISION=[fill in maven plug-in repository revision]

git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/vaadin
cd vaadin
git tag -a -m"$VERSION" $VERSION $FRAMEWORK_REVISION
git push --tags
cd ..

git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/vaadin-screenshots
cd vaadin-screenshots
git tag -a -m"$VERSION" $VERSION $SCREENSHOTS_REVISION
git push --tags
cd ..

git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/maven-integration
cd maven-integration
git tag -a -m"$VERSION" $VERSION $ARCHETYPES_REVISION
git push --tags
cd ..

git clone ssh://$GERRIT_USER@dev.vaadin.com:29418/maven-plugin
cd maven-plugin
git tag -a -m"$VERSION" $VERSION $PLUGIN_REVISION
git push --tags
cd ..
</pre></td></tr>
<tr><td><a href="{tbapi}">Build and publish TestBench API for version {version} if proceeding</a></td></tr>
</table>
</body>
</html>""".format(url=args.buildResultUrl, repoUrl=args.stagingRepo, version=args.version)
</html>""".format(url=args.buildResultUrl, repoUrl=args.stagingRepo, version=args.version, tbapi=args.tbapiUrl)

f = open("result/report.html", 'w')
f.write(content)

+ 1
- 1
server/ivy.xml View File

@@ -36,7 +36,7 @@

<!-- Google App Engine -->
<dependency org="com.google.appengine" name="appengine-api-1.0-sdk"
rev="1.2.1" conf="build-provided,ide,test -> default" />
rev="1.7.7" conf="build-provided,ide,test -> default" />

<!-- Bean Validation API -->
<dependency org="javax.validation" name="validation-api"

+ 12
- 8
server/src/com/vaadin/server/VaadinServlet.java View File

@@ -28,6 +28,7 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -694,17 +695,20 @@ public class VaadinServlet extends HttpServlet implements Constants {
return false;
}

String decodedRequestURI = URLDecoder.decode(request.getRequestURI(),
"UTF-8");
if ((request.getContextPath() != null)
&& (request.getRequestURI().startsWith("/VAADIN/"))) {
serveStaticResourcesInVAADIN(request.getRequestURI(), request,
response);
&& (decodedRequestURI.startsWith("/VAADIN/"))) {
serveStaticResourcesInVAADIN(decodedRequestURI, request, response);
return true;
} else if (request.getRequestURI().startsWith(
request.getContextPath() + "/VAADIN/")) {
}

String decodedContextPath = URLDecoder.decode(request.getContextPath(),
"UTF-8");
if (decodedRequestURI.startsWith(decodedContextPath + "/VAADIN/")) {
serveStaticResourcesInVAADIN(
request.getRequestURI().substring(
request.getContextPath().length()), request,
response);
decodedRequestURI.substring(decodedContextPath.length()),
request, response);
return true;
}


+ 14
- 0
server/src/com/vaadin/server/WebBrowser.java View File

@@ -125,6 +125,20 @@ public class WebBrowser implements Serializable {
return browserDetails.isIE();
}

/**
* Tests whether the user is using Edge.
*
* @return true if the user is using Edge, false if the user is not using
* Edge or if no information on the browser is present
*/
public boolean isEdge() {
if (browserDetails == null) {
return false;
}

return browserDetails.isEdge();
}

/**
* Tests whether the user is using Safari.
*

+ 7
- 0
server/src/com/vaadin/server/communication/AtmospherePushConnection.java View File

@@ -274,6 +274,13 @@ public class AtmospherePushConnection implements PushConnection {
public void disconnect() {
assert isConnected();

if (resource == null) {
// Already disconnected. Should not happen but if it does, we don't
// want to cause NPEs
getLogger()
.fine("AtmospherePushConnection.disconnect() called twice, this should not happen");
return;
}
if (resource.isResumed()) {
// This can happen for long polling because of
// http://dev.vaadin.com/ticket/16919

+ 1
- 1
server/src/com/vaadin/server/communication/FileUploadHandler.java View File

@@ -269,7 +269,7 @@ public class FileUploadHandler implements RequestHandler {
streamVariable = uI.getConnectorTracker().getStreamVariable(
connectorId, variableName);
String secKey = uI.getConnectorTracker().getSeckey(streamVariable);
if (!secKey.equals(parts[3])) {
if (secKey == null || !secKey.equals(parts[3])) {
// TODO Should rethink error handling
return true;
}

+ 29
- 1
server/src/com/vaadin/ui/Grid.java View File

@@ -1167,6 +1167,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,

private int selectionLimit = DEFAULT_MAX_SELECTIONS;

private boolean allSelected;

@Override
public boolean select(final Object... itemIds)
throws IllegalArgumentException {
@@ -1212,6 +1214,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
}
fireSelectionEvent(oldSelection, selection);
}

updateAllSelectedState();

return selectionWillChange;
}

@@ -1277,6 +1282,9 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
selection.removeAll(itemIds);
fireSelectionEvent(oldSelection, selection);
}

updateAllSelectedState();

return hasCommonElements;
}

@@ -1357,6 +1365,8 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
fireSelectionEvent(oldSelection, selection);
}

updateAllSelectedState();

return changed;
}

@@ -1370,6 +1380,13 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
"Vararg array of itemIds may not be null");
}
}

private void updateAllSelectedState() {
if (allSelected != selection.size() >= selectionLimit) {
allSelected = selection.size() >= selectionLimit;
grid.getRpcProxy(GridClientRpc.class).setSelectAll(allSelected);
}
}
}

/**
@@ -3648,10 +3665,21 @@ public class Grid extends AbstractFocusable implements SelectionNotifier,
safeConverter.getPresentationType(), locale);
}

JsonValue encodedValue = renderer.encode(presentationValue);
JsonValue encodedValue;
try {
encodedValue = renderer.encode(presentationValue);
} catch (Exception e) {
getLogger().log(Level.SEVERE, "Unable to encode data", e);
encodedValue = renderer.encode(null);
}

return encodedValue;
}

private static Logger getLogger() {
return Logger.getLogger(AbstractRenderer.class.getName());
}

}

/**

+ 7
- 0
server/src/com/vaadin/ui/HorizontalLayout.java View File

@@ -15,6 +15,8 @@
*/
package com.vaadin.ui;

import com.vaadin.shared.ui.orderedlayout.HorizontalLayoutState;

/**
* Horizontal layout
*
@@ -48,4 +50,9 @@ public class HorizontalLayout extends AbstractOrderedLayout {
addComponents(children);
}

@Override
protected HorizontalLayoutState getState() {
return (HorizontalLayoutState) super.getState();
}

}

+ 7
- 0
server/src/com/vaadin/ui/VerticalLayout.java View File

@@ -15,6 +15,8 @@
*/
package com.vaadin.ui;

import com.vaadin.shared.ui.orderedlayout.VerticalLayoutState;

/**
* Vertical layout
*
@@ -48,4 +50,9 @@ public class VerticalLayout extends AbstractOrderedLayout {
this();
addComponents(children);
}

@Override
protected VerticalLayoutState getState() {
return (VerticalLayoutState) super.getState();
}
}

+ 1
- 1
server/src/com/vaadin/ui/renderers/ImageRenderer.java View File

@@ -58,7 +58,7 @@ public class ImageRenderer extends ClickableRenderer<Resource> {
if (!(resource == null || resource instanceof ExternalResource || resource instanceof ThemeResource)) {
throw new IllegalArgumentException(
"ImageRenderer only supports ExternalResource and ThemeResource ("
+ resource.getClass().getSimpleName() + "given )");
+ resource.getClass().getSimpleName() + " given)");
}

return encode(ResourceReference.create(resource, this, null),

+ 103
- 17
server/tests/src/com/vaadin/server/communication/FileUploadHandlerTest.java View File

@@ -15,50 +15,136 @@
*/
package com.vaadin.server.communication;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import com.vaadin.server.ClientConnector;
import com.vaadin.server.ServletPortletHelper;
import com.vaadin.server.StreamVariable;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinResponse;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.ConnectorTracker;
import com.vaadin.ui.UI;

/**
* Tests whether we get infinite loop if InputStream is already read (#10096)
*/
public class FileUploadHandlerTest {

private FileUploadHandler handler;
private VaadinRequest request;
@Mock private VaadinResponse response;
@Mock private StreamVariable streamVariable;
@Mock private ClientConnector clientConnector;
@Mock private VaadinRequest request;
@Mock private UI ui;
@Mock private ConnectorTracker connectorTracker;
@Mock private VaadinSession session;
@Mock private OutputStream responseOutput;

private int uiId = 123;
private final String connectorId = "connectorId";
private final String variableName = "name";
private final String expectedSecurityKey = "key";

@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);

handler = new FileUploadHandler();
InputStream inputStream = new InputStream() {
private int counter = 0;

mockRequest();
mockConnectorTracker();
mockUi();

when(clientConnector.isConnectorEnabled()).thenReturn(true);
when(streamVariable.getOutputStream()).thenReturn(mock(OutputStream.class));
when(response.getOutputStream()).thenReturn(responseOutput);
}

private void mockConnectorTracker() {
when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey);
when(connectorTracker.getStreamVariable(connectorId, variableName)).thenReturn(streamVariable);
when(connectorTracker.getConnector(connectorId)).thenReturn(clientConnector);
}

private void mockRequest() throws IOException {
when(request.getPathInfo()).thenReturn("/" + ServletPortletHelper.UPLOAD_URL_PREFIX + uiId + "/"+ connectorId + "/" + variableName + "/" + expectedSecurityKey);
when(request.getInputStream()).thenReturn(createInputStream("foobar"));
when(request.getHeader("Content-Length")).thenReturn("6");
when(request.getContentType()).thenReturn("foobar");
}

private InputStream createInputStream(final String content) {
return new InputStream() {
int counter = 0;
byte[] msg = content.getBytes();

@Override
public int read() throws IOException {
counter++;
if (counter > 6) {
throw new RuntimeException(
"-1 is ignored by FileUploadHandler");
if(counter > msg.length + 1) {
throw new AssertionError("-1 was ignored by FileUploadHandler.");
}

if(counter >= msg.length) {
counter++;
return -1;
}
return -1;
}

return msg[counter++];
}
};
request = Mockito.mock(VaadinRequest.class);
Mockito.when(request.getInputStream()).thenReturn(inputStream);
Mockito.when(request.getHeader("Content-Length")).thenReturn("211");
}

private void mockUi() {
when(ui.getConnectorTracker()).thenReturn(connectorTracker);
when(session.getUIById(uiId)).thenReturn(ui);
}

/**
* Tests whether we get infinite loop if InputStream is already read (#10096)
*/
@Test(expected = IOException.class)
public void testStreamEnded() throws IOException {
public void exceptionIsThrownOnUnexpectedEnd() throws IOException {
when(request.getInputStream()).thenReturn(createInputStream(""));
when(request.getHeader("Content-Length")).thenReturn("1");

handler.doHandleSimpleMultipartFileUpload(null, request, null, null,
null, null, null);
}

@Test
public void responseIsSentOnCorrectSecurityKey() throws IOException {
when(connectorTracker.getSeckey(streamVariable)).thenReturn(expectedSecurityKey);

handler.handleRequest(session, request, response);

verify(responseOutput).close();
}

@Test
public void responseIsNotSentOnIncorrectSecurityKey() throws IOException {
when(connectorTracker.getSeckey(streamVariable)).thenReturn("another key expected");

handler.handleRequest(session, request, response);

verifyZeroInteractions(responseOutput);
}

@Test
public void responseIsNotSentOnMissingSecurityKey() throws IOException {
when(connectorTracker.getSeckey(streamVariable)).thenReturn(null);

handler.handleRequest(session, request, response);

verifyZeroInteractions(responseOutput);
}
}

+ 25
- 0
shared/src/com/vaadin/shared/VBrowserDetails.java View File

@@ -41,6 +41,7 @@ public class VBrowserDetails implements Serializable {
private boolean isFirefox = false;
private boolean isOpera = false;
private boolean isIE = false;
private boolean isEdge = false;
private boolean isPhantomJS = false;

private boolean isWindowsPhone;
@@ -88,6 +89,16 @@ public class VBrowserDetails implements Serializable {
isSafari = !isChrome && !isIE && userAgent.indexOf("safari") != -1;
isFirefox = userAgent.indexOf(" firefox/") != -1;
isPhantomJS = userAgent.indexOf("phantomjs/") != -1;
if (userAgent.indexOf(" edge/") != -1) {
isEdge = true;
isChrome = false;
isOpera = false;
isIE = false;
isSafari = false;
isFirefox = false;
isWebKit = false;
isGecko = false;
}

// chromeframe
isChromeFrameCapable = userAgent.indexOf("chromeframe") != -1;
@@ -115,6 +126,8 @@ public class VBrowserDetails implements Serializable {
tmp = tmp.replaceFirst("([0-9]+\\.[0-9]+).*", "$1");
browserEngineVersion = Float.parseFloat(tmp);
}
} else if (isEdge) {
browserEngineVersion = 0;
}
} catch (Exception e) {
// Browser engine version parsing failed
@@ -158,6 +171,9 @@ public class VBrowserDetails implements Serializable {
i = userAgent.indexOf("opera/") + 6;
}
parseVersionString(safeSubstring(userAgent, i, i + 5));
} else if (isEdge) {
int i = userAgent.indexOf(" edge/") + 6;
parseVersionString(safeSubstring(userAgent, i, i + 8));
}
} catch (Exception e) {
// Browser version parsing failed
@@ -372,6 +388,15 @@ public class VBrowserDetails implements Serializable {
return isIE;
}

/**
* Tests if the browser is Edge.
*
* @return true if it is Edge, false otherwise
*/
public boolean isEdge() {
return isEdge;
}

/**
* Tests if the browser is PhantomJS.
*

+ 11
- 0
shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java View File

@@ -55,4 +55,15 @@ public interface GridClientRpc extends ClientRpc {
* Command client Grid to recalculate column widths.
*/
public void recalculateColumnWidths();

/**
* Informs the Grid that all items have been selected or not selected on the
* server side.
*
* @since 7.5.3
* @param allSelected
* <code>true</code> to check the select all checkbox,
* <code>false</code> to uncheck it.
*/
public void setSelectAll(boolean allSelected);
}

+ 2
- 1
uitest/integration_tests.xml View File

@@ -404,7 +404,8 @@
<antcall target="integration-test-osgi" />
<antcall target="integration-test-tomcat7apacheproxy" />
<antcall target="integration-test-websphere8" />
<antcall target="integration-test-websphereportal8" />
<!-- Currently the test system does not have a server for automatic testing of WebSphere Portal 8 -->
<!-- <antcall target="integration-test-websphereportal8" /> -->
</parallel>

</target>

+ 1
- 1
uitest/ivy.xml View File

@@ -31,7 +31,7 @@
rev="4.2.0.Final" conf="build,ide -> default" />
<!-- Google App Engine -->
<dependency org="com.google.appengine" name="appengine-api-1.0-sdk"
rev="1.2.1" conf="build-provided,ide -> default" />
rev="1.7.7" conf="build-provided,ide -> default" />

<!-- LIBRARY DEPENDENCIES (compile time) -->
<!-- Project modules -->

+ 1
- 1
uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java View File

@@ -40,7 +40,7 @@ public class VerifyBrowserVersionTest extends MultiBrowserTest {
// Chrome version does not necessarily match the desired version
// because of auto updates...
browserIdentifier = getExpectedUserAgentString(getDesiredCapabilities())
+ "43";
+ "44";
} else {
browserIdentifier = getExpectedUserAgentString(desiredCapabilities)
+ desiredCapabilities.getVersion();

+ 12
- 2
uitest/src/com/vaadin/tests/components/calendar/NullEventMoveHandler.java View File

@@ -5,17 +5,27 @@ import java.text.SimpleDateFormat;
import java.util.Locale;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Calendar;
import com.vaadin.ui.components.calendar.CalendarComponentEvents;
import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClick;
import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventClickHandler;
import com.vaadin.ui.components.calendar.event.BasicEvent;

public class NullEventMoveHandler extends AbstractTestUI {
public class NullEventMoveHandler extends AbstractTestUIWithLog {
@Override
protected void setup(VaadinRequest request) {
Calendar calendar = getCalendar();

calendar.setHandler((CalendarComponentEvents.EventMoveHandler) null);
calendar.setHandler(new EventClickHandler() {

@Override
public void eventClick(EventClick event) {
log("Clicked on " + event.getCalendarEvent().getCaption());

}
});

addComponent(calendar);
}

+ 15
- 0
uitest/src/com/vaadin/tests/components/calendar/NullEventMoveHandlerTest.java View File

@@ -3,6 +3,7 @@ package com.vaadin.tests.components.calendar;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
@@ -22,12 +23,26 @@ public class NullEventMoveHandlerTest extends DndActionsTest {
assertEventCannotBeMoved();
}

@Test
public void eventIsClickableWhenNotMovableInMonthView() {
getEvent().click();
Assert.assertEquals("1. Clicked on foo", getLogRow(0));
}

@Test
public void eventIsNotMovableInWeekView() {
openWeekView();
assertEventCannotBeMoved();
}

@Test
public void eventIsClickableWhenNotMovableInWeekView() {
openWeekView();
getEvent().findElement(By.className("v-calendar-event-caption"))
.click();
Assert.assertEquals("1. Clicked on foo", getLogRow(0));
}

private void assertEventCannotBeMoved() {
int originalPosition = getEventXPosition();


+ 40
- 0
uitest/src/com/vaadin/tests/components/combobox/ComboboxPopupScrolling.java View File

@@ -0,0 +1,40 @@
package com.vaadin.tests.components.combobox;

import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;

@Theme("valo")
public class ComboboxPopupScrolling extends AbstractTestUIWithLog {
@Override
protected void setup(VaadinRequest request) {
ComboBox combobox = new ComboBox("100px wide combobox");
combobox.setWidth("100px");
combobox.addItem("AMERICAN SAMOA");
combobox.addItem("ANTIGUA AND BARBUDA");

ComboBox combobox2 = new ComboBox("250px wide combobox");
combobox2.setWidth("250px");
combobox2.addItem("AMERICAN SAMOA");
combobox2.addItem("ANTIGUA AND BARBUDA");

ComboBox combobox3 = new ComboBox("Undefined wide combobox");
combobox3.setWidth(null);
combobox3.addItem("AMERICAN SAMOA");
combobox3.addItem("ANTIGUA AND BARBUDA");

ComboBox combobox4 = new ComboBox("Another 100px wide combobox");
combobox4.setWidth("100px");
for (int i = 0; i < 10; i++) {
combobox4.addItem("AMERICAN SAMOA " + i);
combobox4.addItem("ANTIGUA AND BARBUDA " + i);
}

HorizontalLayout hl = new HorizontalLayout(combobox, combobox2,
combobox3, combobox4);
addComponent(hl);
}

}

+ 60
- 0
uitest/src/com/vaadin/tests/components/combobox/ComboboxPopupScrollingTest.java View File

@@ -0,0 +1,60 @@
/*
* 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.combobox;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.tests.tb3.MultiBrowserTest;

public class ComboboxPopupScrollingTest extends MultiBrowserTest {

@Test
public void testNoScrollbarsValo() {
testNoScrollbars("valo");
}

@Test
public void testNoScrollbarsChameleon() {
testNoScrollbars("chameleon");
}

@Test
public void testNoScrollbarsRuno() {
testNoScrollbars("runo");
}

@Test
public void testNoScrollbarsReindeer() {
testNoScrollbars("reindeer");
}

private void testNoScrollbars(String theme) {
openTestURL("theme=" + theme);

for (CustomComboBoxElement cb : $(CustomComboBoxElement.class).all()) {
String caption = cb.getCaption();
cb.openPopup();
WebElement popup = cb.getSuggestionPopup();
WebElement scrollable = popup.findElement(By
.className("v-filterselect-suggestmenu"));
assertNoHorizontalScrollbar(scrollable, caption);
assertNoVerticalScrollbar(scrollable, caption);
}
}

}

+ 40
- 0
uitest/src/com/vaadin/tests/components/combobox/CustomComboBoxElement.java View File

@@ -0,0 +1,40 @@
/*
* 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.combobox;

import org.openqa.selenium.WebElement;

import com.vaadin.testbench.By;
import com.vaadin.testbench.elements.ComboBoxElement;
import com.vaadin.testbench.elementsbase.ServerClass;

@ServerClass("com.vaadin.ui.ComboBox")
public class CustomComboBoxElement extends ComboBoxElement {
private static org.openqa.selenium.By bySuggestionPopup = By
.vaadin("#popup");

public WebElement getSuggestionPopup() {
ensurePopupOpen();
return findElement(bySuggestionPopup);
}

private void ensurePopupOpen() {
if (!isElementPresent(bySuggestionPopup)) {
openPopup();
}
}

}

+ 0
- 5
uitest/src/com/vaadin/tests/components/grid/GridDetailsLocationTest.java View File

@@ -23,7 +23,6 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
@@ -313,10 +312,6 @@ public class GridDetailsLocationTest extends MultiBrowserTest {
checkBoxElement.click(5, 5);
}

private Object executeScript(String string, Object... param) {
return ((JavascriptExecutor) getDriver()).executeScript(string, param);
}

private void scrollAndToggle(int row) {
setRow(row);
getScrollAndToggle().click();

+ 43
- 0
uitest/src/com/vaadin/tests/components/grid/GridWithBrokenRenderer.java View File

@@ -0,0 +1,43 @@
/*
* 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.grid;

import com.vaadin.server.ClassResource;
import com.vaadin.server.Resource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.tests.integration.FlagSeResource;
import com.vaadin.ui.Grid;
import com.vaadin.ui.renderers.ImageRenderer;

public class GridWithBrokenRenderer extends AbstractTestUIWithLog {

@Override
protected void setup(VaadinRequest request) {
final Grid grid = new Grid();
grid.addColumn("short", String.class);
grid.addColumn("icon", Resource.class);
grid.addColumn("country", String.class);

grid.getColumn("icon").setRenderer(new ImageRenderer());
addComponent(grid);

grid.addRow("FI", new ClassResource("fi.gif"), "Finland");
grid.addRow("SE", new FlagSeResource(), "Sweden");

}

}

+ 41
- 0
uitest/src/com/vaadin/tests/components/grid/GridWithBrokenRendererTest.java View File

@@ -0,0 +1,41 @@
/*
* 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.grid;

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

import com.vaadin.testbench.elements.GridElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class GridWithBrokenRendererTest extends SingleBrowserTest {

@Test
public void ensureRendered() {
openTestURL();
GridElement grid = $(GridElement.class).first();
assertRow(grid, 0, "FI", "", "Finland");
assertRow(grid, 1, "SE", "", "Sweden");
}

private void assertRow(GridElement grid, int row, String... texts) {
for (int column = 0; column < texts.length; column++) {
Assert.assertEquals("Cell " + row + "," + column, texts[column],
grid.getCell(row, column).getText());
}

}
}

+ 20
- 0
uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java View File

@@ -792,6 +792,26 @@ public class GridBasicFeatures extends AbstractComponentTest<Grid> {
c.setColumnReorderingAllowed(value);
}
});

createClickAction("Select all", "State", new Command<Grid, String>() {
@Override
public void execute(Grid c, String value, Object data) {
SelectionModel selectionModel = c.getSelectionModel();
if (selectionModel instanceof SelectionModel.Multi) {
((SelectionModel.Multi) selectionModel).selectAll();
}
}
}, null);

createClickAction("Select none", "State", new Command<Grid, String>() {
@Override
public void execute(Grid c, String value, Object data) {
SelectionModel selectionModel = c.getSelectionModel();
if (selectionModel instanceof SelectionModel.Multi) {
((SelectionModel.Multi) selectionModel).deselectAll();
}
}
}, null);
}

protected void createHeaderActions() {

+ 2
- 0
uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java View File

@@ -207,6 +207,8 @@ public abstract class GridEditorTest extends GridBasicFeaturesTest {

assertTrue("Noneditable cell should contain v-grid-cell classname",
classNames.contains("v-grid-cell"));

assertNoErrorNotifications();
}

@Test

+ 58
- 0
uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java View File

@@ -20,8 +20,10 @@ import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedCondition;

import com.vaadin.testbench.By;
import com.vaadin.testbench.elements.GridElement;
@@ -335,6 +337,62 @@ public class GridSelectionTest extends GridBasicFeaturesTest {
getRow(5).isSelected());
}

@Test
public void testSelectionCheckBoxesHaveStyleNames() {
openTestURL();

setSelectionModelMulti();

assertTrue(
"Selection column CheckBox should have the proper style name set",
getGridElement().getCell(0, 0).findElement(By.tagName("span"))
.getAttribute("class")
.contains("v-grid-selection-checkbox"));

GridCellElement header = getGridElement().getHeaderCell(0, 0);
assertTrue("Select all CheckBox should have the proper style name set",
header.findElement(By.tagName("span")).getAttribute("class")
.contains("v-grid-select-all-checkbox"));
}

@Test
public void testServerSideSelectTogglesSelectAllCheckBox() {
openTestURL();

setSelectionModelMulti();
GridCellElement header = getGridElement().getHeaderCell(0, 0);

WebElement selectAll = header.findElement(By.tagName("input"));

selectMenuPath("Component", "State", "Select all");
waitUntilCheckBoxValue(selectAll, true);
assertTrue("Select all CheckBox wasn't selected as expected",
selectAll.isSelected());

selectMenuPath("Component", "State", "Select none");
waitUntilCheckBoxValue(selectAll, false);
assertFalse("Select all CheckBox was selected unexpectedly",
selectAll.isSelected());

selectMenuPath("Component", "State", "Select all");
waitUntilCheckBoxValue(selectAll, true);
getGridElement().getCell(5, 0).click();
waitUntilCheckBoxValue(selectAll, false);
assertFalse("Select all CheckBox was selected unexpectedly",
selectAll.isSelected());
}

private void waitUntilCheckBoxValue(final WebElement checkBoxElememnt,
final boolean expectedValue) {
waitUntil(new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver input) {
return expectedValue ? checkBoxElememnt.isSelected()
: !checkBoxElememnt.isSelected();
}
}, 5);
}

private void setSelectionModelMulti() {
selectMenuPath("Component", "State", "Selection mode", "multi");
}

+ 43
- 0
uitest/src/com/vaadin/tests/components/tabsheet/TabSheetInSplitPanel.java View File

@@ -0,0 +1,43 @@
/*
* 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.tabsheet;

import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Label;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalSplitPanel;
import com.vaadin.ui.themes.ValoTheme;

@Theme("valo")
public class TabSheetInSplitPanel extends UI {

@Override
protected void init(VaadinRequest request) {
VerticalSplitPanel verticalSplitter = new VerticalSplitPanel();
setContent(verticalSplitter);
verticalSplitter.setSizeFull();
TabSheet t = new TabSheet();
t.setHeight("100%");
t.addTab(new Label("Hello in tab"), "Hello tab");
t.setStyleName(ValoTheme.TABSHEET_FRAMED);
verticalSplitter.addComponent(t);
verticalSplitter.addComponent(new Label("Hello"));

}

}

+ 43
- 0
uitest/src/com/vaadin/tests/components/tabsheet/TabSheetInSplitPanelTest.java View File

@@ -0,0 +1,43 @@
/*
* 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.tabsheet;

import java.util.List;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.elements.TabSheetElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class TabSheetInSplitPanelTest extends MultiBrowserTest {

@Test
public void ensureNoScrollbars() {
openTestURL();
TabSheetElement ts = $(TabSheetElement.class).first();
List<WebElement> scrollables = ts.findElements(By
.xpath("//*[contains(@class,'v-scrollable')]"));
for (WebElement scrollable : scrollables) {
assertNoHorizontalScrollbar(scrollable,
"Element should not have a horizontal scrollbar");
assertNoVerticalScrollbar(scrollable,
"Element should not have a vertical scrollbar");
}
}

}

+ 51
- 0
uitest/src/com/vaadin/tests/components/treetable/TreeTableScrollOnExpand.java View File

@@ -0,0 +1,51 @@
/*
* 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.treetable;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUI;
import com.vaadin.ui.TreeTable;

public class TreeTableScrollOnExpand extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
TreeTable t = new TreeTable();
t.setSelectable(true);
t.setImmediate(true);
t.setSizeFull();
t.addContainerProperty("Name", String.class, "null");
for (int i = 1; i <= 100; i++) {
String parentID = "Item " + i;
Object parent = t.addItem(new Object[] { parentID }, parentID);
String childID = "Item " + (100 + i);
Object child = t.addItem(new Object[] { childID }, childID);
t.getContainerDataSource().setParent(childID, parentID);
}
addComponent(t);
}

@Override
public Integer getTicketNumber() {
return 18247;
}

@Override
public String getTestDescription() {
return "After selecting an item and scrolling it out of view, TreeTable should not scroll to the "
+ "selected item when expanding an item.";
}
}

+ 46
- 0
uitest/src/com/vaadin/tests/components/treetable/TreeTableScrollOnExpandTest.java View File

@@ -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.treetable;

import static org.junit.Assert.assertEquals;

import java.io.IOException;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.elements.TreeTableElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class TreeTableScrollOnExpandTest extends MultiBrowserTest {

@Test
public void testScrollOnExpand() throws InterruptedException, IOException {
openTestURL();
TreeTableElement tt = $(TreeTableElement.class).first();
tt.getRow(0).click();
tt.scroll(300);
sleep(1000);
tt.getRow(20).toggleExpanded();
// Need to wait a bit to avoid accepting the case where the TreeTable is
// in the desired state only for a short while.
sleep(1000);
WebElement focusedRow = getDriver().findElement(
By.className("v-table-focus"));
assertEquals("Item 21", focusedRow.getText());
}
}

+ 49
- 0
uitest/src/com/vaadin/tests/components/window/GridInWindow.java View File

@@ -0,0 +1,49 @@
/*
* 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.window;

import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Button;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Window;

public class GridInWindow extends AbstractTestUIWithLog {

@Override
protected void setup(VaadinRequest request) {
final Grid grid = new Grid();

grid.addColumn("Hidable column").setHidable(true);
grid.addRow("Close and reopen and it vanishes");

Button popupButton = new Button("Open PopUp",
new Button.ClickListener() {
@Override
public void buttonClick(Button.ClickEvent event) {
Window subWindow = new Window("Sub-window");
subWindow.setContent(grid);
subWindow.setWidth(600, Unit.PIXELS);
subWindow.setWidth(400, Unit.PIXELS);
getUI().addWindow(subWindow);
}
});

addComponent(popupButton);

}

}

+ 36
- 0
uitest/src/com/vaadin/tests/components/window/GridInWindowTest.java View File

@@ -0,0 +1,36 @@
/*
* 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.window;

import org.junit.Test;

import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.tests.tb3.SingleBrowserTest;
import com.vaadin.tests.tb3.newelements.WindowElement;

public class GridInWindowTest extends SingleBrowserTest {

@Test
public void ensureAttachInHierachyChange() {
openTestURL("debug");
$(ButtonElement.class).first().click();
assertNoErrorNotifications();
$(WindowElement.class).first().close();
assertNoErrorNotifications();
$(ButtonElement.class).first().click();
assertNoErrorNotifications();
}
}

+ 62
- 0
uitest/src/com/vaadin/tests/components/window/OpenModalWindowAndFocusField.java View File

@@ -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.window;

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.TextArea;
import com.vaadin.ui.Window;

public class OpenModalWindowAndFocusField extends AbstractTestUIWithLog {

@Override
protected void setup(VaadinRequest request) {
Button button = new Button("Open modal and focus textarea");
button.setId("openFocus");
button.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
open(true);
}
});
addComponent(button);

button = new Button("Only open modal");
button.setId("open");
button.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
open(false);
}

});
addComponent(button);

}

private void open(boolean focus) {
Window wind = new Window();
wind.setModal(true);
TextArea ta = new TextArea();
wind.setContent(ta);
addWindow(wind);
if (focus) {
ta.focus();
}
}
}

+ 48
- 0
uitest/src/com/vaadin/tests/components/window/OpenModalWindowAndFocusFieldTest.java View File

@@ -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.window;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.TextAreaElement;
import com.vaadin.tests.tb3.MultiBrowserTest;

public class OpenModalWindowAndFocusFieldTest extends MultiBrowserTest {

@Test
public void openModalAndFocusField() {
openTestURL();
$(ButtonElement.class).id("openFocus").click();
TextAreaElement textArea = $(TextAreaElement.class).first();

assertElementsEquals(textArea, getActiveElement());
}

@Test
public void openModal() {
openTestURL();
$(ButtonElement.class).id("open").click();
// WindowElement window = $(WindowElement.class).first();
WebElement windowFocusElement = findElement(By
.xpath("//div[@class='v-window-contents']/div[@class='v-scrollable']"));

assertElementsEquals(windowFocusElement, getActiveElement());
}

}

+ 94
- 0
uitest/src/com/vaadin/tests/push/ManualLongPollingPushUI.java View File

@@ -0,0 +1,94 @@
/*
* 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.push;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.vaadin.annotations.Push;
import com.vaadin.server.VaadinRequest;
import com.vaadin.shared.communication.PushMode;
import com.vaadin.shared.ui.ui.Transport;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;

@Push(value = PushMode.MANUAL, transport = Transport.LONG_POLLING)
public class ManualLongPollingPushUI extends AbstractTestUIWithLog {

ExecutorService executor = Executors.newFixedThreadPool(1);

@Override
protected void setup(VaadinRequest request) {
Button b = new Button("Manual push after 1s",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
executor.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
access(new Runnable() {

@Override
public void run() {
log("Logged after 1s, followed by manual push");
push();
}
});

}
});
}
});
addComponent(b);

b = new Button("Double manual push after 1s",
new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
executor.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
access(new Runnable() {

@Override
public void run() {
log("First message logged after 1s, followed by manual push");
push();
log("Second message logged after 1s, followed by manual push");
push();
}
});

}
});
}
});
addComponent(b);

}

}

+ 54
- 0
uitest/src/com/vaadin/tests/push/ManualLongPollingPushUITest.java View File

@@ -0,0 +1,54 @@
/*
* 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.push;

import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;

import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.tests.tb3.SingleBrowserTest;

public class ManualLongPollingPushUITest extends SingleBrowserTest {

@Test
public void doubleManualPushDoesNotFreezeApplication() {
openTestURL();
$(ButtonElement.class).caption("Double manual push after 1s").first()
.click();
waitUntilLogText("2. Second message logged after 1s, followed by manual push");
$(ButtonElement.class).caption("Manual push after 1s").first().click();
waitUntilLogText("3. Logged after 1s, followed by manual push");
}

private void waitUntilLogText(final String expected) {
waitUntil(new ExpectedCondition<Boolean>() {
private String actual;

@Override
public Boolean apply(WebDriver arg0) {
actual = getLogRow(0);
return expected.equals(actual);
}

@Override
public String toString() {
return String.format("log text to become '%s' (was: '%s')",
expected, actual);
}
});
}
}

+ 52
- 0
uitest/src/com/vaadin/tests/resources/SpecialCharsInThemeResources.java View File

@@ -0,0 +1,52 @@
/*
* 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.resources;

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

import com.vaadin.tests.tb3.SingleBrowserTest;

public class SpecialCharsInThemeResources extends SingleBrowserTest {

@Test
public void loadThemeResource() {
loadResource("/VAADIN/themes/tests-tickets/ordinary.txt");
checkSource();
}

@Test
public void loadThemeResourceWithPercentage() {
loadResource("/VAADIN/themes/tests-tickets/percentagein%2520name.txt");
checkSource();
}

@Test
public void loadThemeResourceWithSpecialChars() {
loadResource("/VAADIN/themes/tests-tickets/folder%20with%20space/resource%20with%20special%20$chars@.txt");
checkSource();
}

private void loadResource(String path) {
getDriver().get(getBaseURL() + path);
}

private void checkSource() {
String source = getDriver().getPageSource();
Assert.assertTrue("Incorrect contents (was: " + source + ")",
source.contains("Just ordinary contents here"));
}
}

+ 92
- 2
uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java View File

@@ -50,6 +50,7 @@ import org.openqa.selenium.interactions.Keyboard;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.interactions.internal.Coordinates;
import org.openqa.selenium.internal.Locatable;
import org.openqa.selenium.internal.WrapsElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
@@ -368,8 +369,8 @@ public abstract class AbstractTB3Test extends ParallelTest {
* {@link org.openqa.selenium.JavascriptExecutor#executeScript(String, Object...)}
* returns
*/
protected Object executeScript(String script) {
return ((JavascriptExecutor) getDriver()).executeScript(script);
protected Object executeScript(String script, Object... args) {
return ((JavascriptExecutor) getDriver()).executeScript(script, args);
}

/**
@@ -1105,4 +1106,93 @@ public abstract class AbstractTB3Test extends ParallelTest {
return isElementPresent(By.className("v-debugwindow"));
}

protected void assertNoHorizontalScrollbar(WebElement element,
String errorMessage) {
// IE rounds clientWidth/clientHeight down and scrollHeight/scrollWidth
// up, so using clientWidth/clientHeight will fail if the element height
// is not an integer
int clientWidth = getClientWidth(element);
int scrollWidth = getScrollWidth(element);
boolean hasScrollbar = scrollWidth > clientWidth;

Assert.assertFalse(
"The element should not have a horizontal scrollbar (scrollWidth: "
+ scrollWidth + ", clientWidth: " + clientWidth + "): "
+ errorMessage, hasScrollbar);
}

protected void assertNoVerticalScrollbar(WebElement element,
String errorMessage) {
// IE rounds clientWidth/clientHeight down and scrollHeight/scrollWidth
// up, so using clientWidth/clientHeight will fail if the element height
// is not an integer
int clientHeight = getClientHeight(element);
int scrollHeight = getScrollHeight(element);
boolean hasScrollbar = scrollHeight > clientHeight;

Assert.assertFalse(
"The element should not have a vertical scrollbar (scrollHeight: "
+ scrollHeight + ", clientHeight: " + clientHeight
+ "): " + errorMessage, hasScrollbar);
}

protected int getScrollHeight(WebElement element) {
return ((Number) executeScript("return arguments[0].scrollHeight;",
element)).intValue();
}

protected int getScrollWidth(WebElement element) {
return ((Number) executeScript("return arguments[0].scrollWidth;",
element)).intValue();
}

/**
* Returns client height rounded up instead of as double because of IE9
* issues: https://dev.vaadin.com/ticket/18469
*/
protected int getClientHeight(WebElement e) {
String script;
if (BrowserUtil.isIE8(getDesiredCapabilities())) {
script = "return arguments[0].clientHeight;"; //
} else {
script = "var cs = window.getComputedStyle(arguments[0]);"
+ "return Math.ceil(parseFloat(cs.height)+parseFloat(cs.paddingTop)+parseFloat(cs.paddingBottom));";
}
return ((Number) executeScript(script, e)).intValue();
}

/**
* Returns client width rounded up instead of as double because of IE9
* issues: https://dev.vaadin.com/ticket/18469
*/
protected int getClientWidth(WebElement e) {
String script;
if (BrowserUtil.isIE8(getDesiredCapabilities())) {
script = "return arguments[0].clientWidth;";
} else {
script = "var cs = window.getComputedStyle(arguments[0]);"
+ "var h = parseFloat(cs.width)+parseFloat(cs.paddingLeft)+parseFloat(cs.paddingRight);"
+ "return Math.ceil(h);";
}

return ((Number) executeScript(script, e)).intValue();
}

protected void assertElementsEquals(WebElement expectedElement,
WebElement actualElement) {
while (expectedElement instanceof WrapsElement) {
expectedElement = ((WrapsElement) expectedElement)
.getWrappedElement();
}
while (actualElement instanceof WrapsElement) {
actualElement = ((WrapsElement) actualElement).getWrappedElement();
}

Assert.assertEquals(expectedElement, actualElement);
}

protected WebElement getActiveElement() {
return (WebElement) executeScript("return document.activeElement;");

}
}

+ 10
- 0
uitest/src/com/vaadin/tests/tb3/newelements/WindowElement.java View File

@@ -14,6 +14,7 @@ public class WindowElement extends com.vaadin.testbench.elements.WindowElement {

private final String restoreBoxClass = "v-window-restorebox";
private final String maximizeBoxClass = "v-window-maximizebox";
private final String closeBoxClass = "v-window-closebox";

public void restore() {
if (isMaximized()) {
@@ -63,4 +64,13 @@ public class WindowElement extends com.vaadin.testbench.elements.WindowElement {
public String getCaption() {
return findElement(By.className("v-window-header")).getText();
}

private WebElement getCloseButton() {
return findElement(By.className(closeBoxClass));
}

public void close() {
getCloseButton().click();

}
}

Loading…
Cancel
Save