summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Koskinen <anna@vaadin.com>2015-03-13 12:33:24 +0200
committerJohannes Tuikkala <johannes@vaadin.com>2015-03-17 16:07:32 +0200
commita5cf8109f4d419a350614f77404a25b2ff991fd2 (patch)
tree41e1dd401705367a053fd53ad0314cb372462bff
parent504809f3f1e49328e33b17fac2f3f4ceab276665 (diff)
downloadvaadin-framework-a5cf8109f4d419a350614f77404a25b2ff991fd2.tar.gz
vaadin-framework-a5cf8109f4d419a350614f77404a25b2ff991fd2.zip
VScrollTable and WidgetUtil from 7.4.1 to 7.2.6 without DeferredWorker
Change-Id: I01a4b67ddebcf6f868250bf149e507a011ef9d1e
-rw-r--r--client/src/com/vaadin/client/WidgetUtil.java1462
-rw-r--r--client/src/com/vaadin/client/ui/VScrollTable.java903
-rw-r--r--ivysettings.xml4
-rw-r--r--uitest/integration_tests.xml5
-rw-r--r--uitest/ivy.xml28
-rw-r--r--uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java1
-rw-r--r--uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java9
-rw-r--r--uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java9
-rw-r--r--uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java11
-rw-r--r--uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java9
-rw-r--r--uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java13
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java15
-rw-r--r--uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java4
-rw-r--r--uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java15
-rw-r--r--uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java10
-rw-r--r--uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java58
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java62
-rw-r--r--uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java70
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java7
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java8
-rw-r--r--uitest/src/com/vaadin/tests/push/ReconnectTest.java12
-rw-r--r--uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java72
-rw-r--r--uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java88
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java771
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AffectedTB3TestLocator.java92
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java28
-rw-r--r--uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java13
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ChangedTB3TestLocator.java170
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java44
-rw-r--r--uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java106
-rwxr-xr-xuitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java8
-rw-r--r--uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java131
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java203
-rw-r--r--uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java10
-rw-r--r--uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java31
-rw-r--r--uitest/src/com/vaadin/tests/tb3/TB3Runner.java363
-rw-r--r--uitest/src/com/vaadin/tests/tb3/TB3TestLocator.java218
-rw-r--r--uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java240
-rw-r--r--uitest/src/com/vaadin/tests/tb3/VaadinBrowserFactory.java60
-rw-r--r--uitest/src/com/vaadin/tests/tb3/WebsocketTest.java43
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java2
-rw-r--r--uitest/tb3test.xml84
61 files changed, 3771 insertions, 1860 deletions
diff --git a/client/src/com/vaadin/client/WidgetUtil.java b/client/src/com/vaadin/client/WidgetUtil.java
new file mode 100644
index 0000000000..5f88f6da46
--- /dev/null
+++ b/client/src/com/vaadin/client/WidgetUtil.java
@@ -0,0 +1,1462 @@
+/*
+ * 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.client;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Logger;
+
+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.AnchorElement;
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Node;
+import com.google.gwt.dom.client.NodeList;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.dom.client.Style.Display;
+import com.google.gwt.dom.client.Style.Unit;
+import com.google.gwt.dom.client.Touch;
+import com.google.gwt.event.dom.client.KeyEvent;
+import com.google.gwt.regexp.shared.MatchResult;
+import com.google.gwt.regexp.shared.RegExp;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.EventListener;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.shared.util.SharedUtil;
+
+/**
+ * Utility methods which are related to client side code only
+ */
+public class WidgetUtil {
+
+ /**
+ * Helper method for debugging purposes.
+ *
+ * Stops execution on firefox browsers on a breakpoint.
+ *
+ */
+ public static native void browserDebugger()
+ /*-{
+ if($wnd.console)
+ debugger;
+ }-*/;
+
+ /**
+ * Helper method for a bug fix #14041. For mozilla getKeyCode return 0 for
+ * space bar (because space is considered as char). If return 0 use
+ * getCharCode.
+ *
+ * @param event
+ * @return return key code
+ * @since 7.2.4
+ */
+ public static int getKeyCode(KeyEvent<?> event) {
+ int keyCode = event.getNativeEvent().getKeyCode();
+ if (keyCode == 0) {
+ keyCode = event.getNativeEvent().getCharCode();
+ }
+ return keyCode;
+ }
+
+ /**
+ *
+ * Returns the topmost element of from given coordinates.
+ *
+ * TODO fix crossplat issues clientX vs pageX. See quircksmode. Not critical
+ * for vaadin as we scroll div istead of page.
+ *
+ * @param x
+ * @param y
+ * @return the element at given coordinates
+ */
+ public static native Element getElementFromPoint(int clientX, int clientY)
+ /*-{
+ var el = $wnd.document.elementFromPoint(clientX, clientY);
+ // Call elementFromPoint two times to make sure IE8 also returns something sensible if the application is running in an iframe
+ el = $wnd.document.elementFromPoint(clientX, clientY);
+ if(el != null && el.nodeType == 3) {
+ el = el.parentNode;
+ }
+ return el;
+ }-*/;
+
+ public static float parseRelativeSize(String size) {
+ if (size == null || !size.endsWith("%")) {
+ return -1;
+ }
+
+ try {
+ return Float.parseFloat(size.substring(0, size.length() - 1));
+ } catch (Exception e) {
+ getLogger().warning("Unable to parse relative size");
+ return -1;
+ }
+ }
+
+ private static final Element escapeHtmlHelper = DOM.createDiv();
+
+ /**
+ * Converts html entities to text.
+ *
+ * @param html
+ * @return escaped string presentation of given html
+ */
+ public static String escapeHTML(String html) {
+ DOM.setInnerText(escapeHtmlHelper, html);
+ String escapedText = DOM.getInnerHTML(escapeHtmlHelper);
+ if (BrowserInfo.get().isIE8()) {
+ // #7478 IE8 "incorrectly" returns "<br>" for newlines set using
+ // setInnerText. The same for " " which is converted to "&nbsp;"
+ escapedText = escapedText.replaceAll("<(BR|br)>", "\n");
+ escapedText = escapedText.replaceAll("&nbsp;", " ");
+ }
+ return escapedText;
+ }
+
+ /**
+ * Escapes the string so it is safe to write inside an HTML attribute.
+ *
+ * @param attribute
+ * The string to escape
+ * @return An escaped version of <literal>attribute</literal>.
+ */
+ public static String escapeAttribute(String attribute) {
+ if (attribute == null) {
+ return "";
+ }
+ attribute = attribute.replace("\"", "&quot;");
+ attribute = attribute.replace("'", "&#39;");
+ attribute = attribute.replace(">", "&gt;");
+ attribute = attribute.replace("<", "&lt;");
+ attribute = attribute.replace("&", "&amp;");
+ return attribute;
+ }
+
+ /**
+ * Clones given element as in JavaScript.
+ *
+ * Deprecate this if there appears similar method into GWT someday.
+ *
+ * @param element
+ * @param deep
+ * clone child tree also
+ * @return
+ */
+ public static native Element cloneNode(Element element, boolean deep)
+ /*-{
+ return element.cloneNode(deep);
+ }-*/;
+
+ public static int measureHorizontalPaddingAndBorder(Element element,
+ int paddingGuess) {
+ String originalWidth = DOM.getStyleAttribute(element, "width");
+
+ int originalOffsetWidth = element.getOffsetWidth();
+ int widthGuess = (originalOffsetWidth - paddingGuess);
+ if (widthGuess < 1) {
+ widthGuess = 1;
+ }
+ element.getStyle().setWidth(widthGuess, Unit.PX);
+ int padding = element.getOffsetWidth() - widthGuess;
+
+ element.getStyle().setProperty("width", originalWidth);
+
+ return padding;
+ }
+
+ public static int measureVerticalPaddingAndBorder(Element element,
+ int paddingGuess) {
+ String originalHeight = DOM.getStyleAttribute(element, "height");
+ int originalOffsetHeight = element.getOffsetHeight();
+ int widthGuess = (originalOffsetHeight - paddingGuess);
+ if (widthGuess < 1) {
+ widthGuess = 1;
+ }
+ element.getStyle().setHeight(widthGuess, Unit.PX);
+ int padding = element.getOffsetHeight() - widthGuess;
+
+ element.getStyle().setProperty("height", originalHeight);
+ return padding;
+ }
+
+ public static int measureHorizontalBorder(Element element) {
+ int borders;
+
+ if (BrowserInfo.get().isIE()) {
+ String width = element.getStyle().getProperty("width");
+ String height = element.getStyle().getProperty("height");
+
+ int offsetWidth = element.getOffsetWidth();
+ int offsetHeight = element.getOffsetHeight();
+ if (offsetHeight < 1) {
+ offsetHeight = 1;
+ }
+ if (offsetWidth < 1) {
+ offsetWidth = 10;
+ }
+ element.getStyle().setPropertyPx("height", offsetHeight);
+ element.getStyle().setPropertyPx("width", offsetWidth);
+
+ borders = element.getOffsetWidth() - element.getClientWidth();
+
+ element.getStyle().setProperty("width", width);
+ element.getStyle().setProperty("height", height);
+ } else {
+ borders = element.getOffsetWidth()
+ - element.getPropertyInt("clientWidth");
+ }
+ assert borders >= 0;
+
+ return borders;
+ }
+
+ public static int measureVerticalBorder(Element element) {
+ int borders;
+ if (BrowserInfo.get().isIE()) {
+ String width = element.getStyle().getProperty("width");
+ String height = element.getStyle().getProperty("height");
+
+ int offsetWidth = element.getOffsetWidth();
+ int offsetHeight = element.getOffsetHeight();
+ if (offsetHeight < 1) {
+ offsetHeight = 1;
+ }
+ if (offsetWidth < 1) {
+ offsetWidth = 10;
+ }
+ element.getStyle().setPropertyPx("width", offsetWidth);
+
+ element.getStyle().setPropertyPx("height", offsetHeight);
+
+ borders = element.getOffsetHeight()
+ - element.getPropertyInt("clientHeight");
+
+ element.getStyle().setProperty("height", height);
+ element.getStyle().setProperty("width", width);
+ } else {
+ borders = element.getOffsetHeight()
+ - element.getPropertyInt("clientHeight");
+ }
+ assert borders >= 0;
+
+ return borders;
+ }
+
+ public static int measureMarginLeft(Element element) {
+ return element.getAbsoluteLeft()
+ - element.getParentElement().getAbsoluteLeft();
+ }
+
+ public static int setHeightExcludingPaddingAndBorder(Widget widget,
+ String height, int paddingBorderGuess) {
+ if (height.equals("")) {
+ setHeight(widget, "");
+ return paddingBorderGuess;
+ } else if (height.endsWith("px")) {
+ int pixelHeight = Integer.parseInt(height.substring(0,
+ height.length() - 2));
+ return setHeightExcludingPaddingAndBorder(widget.getElement(),
+ pixelHeight, paddingBorderGuess, false);
+ } else {
+ // Set the height in unknown units
+ setHeight(widget, height);
+ // Use the offsetWidth
+ return setHeightExcludingPaddingAndBorder(widget.getElement(),
+ widget.getOffsetHeight(), paddingBorderGuess, true);
+ }
+ }
+
+ private static void setWidth(Widget widget, String width) {
+ widget.getElement().getStyle().setProperty("width", width);
+ }
+
+ private static void setHeight(Widget widget, String height) {
+ widget.getElement().getStyle().setProperty("height", height);
+ }
+
+ public static int setWidthExcludingPaddingAndBorder(Widget widget,
+ String width, int paddingBorderGuess) {
+ if (width.equals("")) {
+ setWidth(widget, "");
+ return paddingBorderGuess;
+ } else if (width.endsWith("px")) {
+ int pixelWidth = Integer.parseInt(width.substring(0,
+ width.length() - 2));
+ return setWidthExcludingPaddingAndBorder(widget.getElement(),
+ pixelWidth, paddingBorderGuess, false);
+ } else {
+ setWidth(widget, width);
+ return setWidthExcludingPaddingAndBorder(widget.getElement(),
+ widget.getOffsetWidth(), paddingBorderGuess, true);
+ }
+ }
+
+ public static int setWidthExcludingPaddingAndBorder(Element element,
+ int requestedWidth, int horizontalPaddingBorderGuess,
+ boolean requestedWidthIncludesPaddingBorder) {
+
+ int widthGuess = requestedWidth - horizontalPaddingBorderGuess;
+ if (widthGuess < 0) {
+ widthGuess = 0;
+ }
+
+ element.getStyle().setWidth(widthGuess, Unit.PX);
+ int captionOffsetWidth = DOM.getElementPropertyInt(element,
+ "offsetWidth");
+
+ int actualPadding = captionOffsetWidth - widthGuess;
+
+ if (requestedWidthIncludesPaddingBorder) {
+ actualPadding += actualPadding;
+ }
+
+ if (actualPadding != horizontalPaddingBorderGuess) {
+ int w = requestedWidth - actualPadding;
+ if (w < 0) {
+ // Cannot set negative width even if we would want to
+ w = 0;
+ }
+ element.getStyle().setWidth(w, Unit.PX);
+
+ }
+
+ return actualPadding;
+
+ }
+
+ public static int setHeightExcludingPaddingAndBorder(Element element,
+ int requestedHeight, int verticalPaddingBorderGuess,
+ boolean requestedHeightIncludesPaddingBorder) {
+
+ int heightGuess = requestedHeight - verticalPaddingBorderGuess;
+ if (heightGuess < 0) {
+ heightGuess = 0;
+ }
+
+ element.getStyle().setHeight(heightGuess, Unit.PX);
+ int captionOffsetHeight = DOM.getElementPropertyInt(element,
+ "offsetHeight");
+
+ int actualPadding = captionOffsetHeight - heightGuess;
+
+ if (requestedHeightIncludesPaddingBorder) {
+ actualPadding += actualPadding;
+ }
+
+ if (actualPadding != verticalPaddingBorderGuess) {
+ int h = requestedHeight - actualPadding;
+ if (h < 0) {
+ // Cannot set negative height even if we would want to
+ h = 0;
+ }
+ element.getStyle().setHeight(h, Unit.PX);
+
+ }
+
+ return actualPadding;
+
+ }
+
+ public static void setFloat(Element element, String value) {
+ if (BrowserInfo.get().isIE()) {
+ element.getStyle().setProperty("styleFloat", value);
+ } else {
+ element.getStyle().setProperty("cssFloat", value);
+ }
+ }
+
+ private static int detectedScrollbarSize = -1;
+
+ public static int getNativeScrollbarSize() {
+ if (detectedScrollbarSize < 0) {
+ Element scroller = DOM.createDiv();
+ scroller.getStyle().setProperty("width", "50px");
+ scroller.getStyle().setProperty("height", "50px");
+ scroller.getStyle().setProperty("overflow", "scroll");
+ scroller.getStyle().setProperty("position", "absolute");
+ scroller.getStyle().setProperty("marginLeft", "-5000px");
+ RootPanel.getBodyElement().appendChild(scroller);
+ detectedScrollbarSize = scroller.getOffsetWidth()
+ - scroller.getPropertyInt("clientWidth");
+
+ RootPanel.getBodyElement().removeChild(scroller);
+ }
+ return detectedScrollbarSize;
+ }
+
+ /**
+ * Defers the execution of {@link #runWebkitOverflowAutoFix(Element)}
+ *
+ * @since 7.2.6
+ * @param elem
+ * with overflow auto
+ */
+ public static void runWebkitOverflowAutoFixDeferred(final Element elem) {
+ Scheduler.get().scheduleDeferred(new Command() {
+
+ @Override
+ public void execute() {
+ WidgetUtil.runWebkitOverflowAutoFix(elem);
+ }
+ });
+
+ }
+
+ /**
+ * Run workaround for webkits overflow auto issue.
+ *
+ * See: our bug #2138 and https://bugs.webkit.org/show_bug.cgi?id=21462
+ *
+ * @param elem
+ * with overflow auto
+ */
+ public static void runWebkitOverflowAutoFix(final Element elem) {
+ // Add max version if fix lands sometime to Webkit
+ // Starting from Opera 11.00, also a problem in Opera
+ if (BrowserInfo.get().requiresOverflowAutoFix()) {
+ final String originalOverflow = elem.getStyle().getProperty(
+ "overflow");
+ final String originalOverflowX = elem.getStyle().getProperty(
+ "overflowX");
+ final String originalOverflowY = elem.getStyle().getProperty(
+ "overflowY");
+ if ("hidden".equals(originalOverflow)
+ || "hidden".equals(originalOverflowX)
+ || "hidden".equals(originalOverflowY)) {
+ return;
+ }
+
+ // check the scrolltop value before hiding the element
+ final int scrolltop = elem.getScrollTop();
+ final int scrollleft = elem.getScrollLeft();
+ elem.getStyle().setProperty("overflow", "hidden");
+
+ Scheduler.get().scheduleDeferred(new Command() {
+ @Override
+ public void execute() {
+ // Dough, Safari scroll auto means actually just a moped
+ elem.getStyle().setProperty("overflow", originalOverflow);
+ if (!originalOverflowX.isEmpty()) {
+ elem.getStyle().setProperty("overflowX",
+ originalOverflowX);
+ }
+ if (!originalOverflowY.isEmpty()) {
+ elem.getStyle().setProperty("overflowY",
+ originalOverflowY);
+ }
+
+ if (scrolltop > 0 || elem.getScrollTop() > 0) {
+ int scrollvalue = scrolltop;
+ if (scrollvalue == 0) {
+ // mysterious are the ways of webkits scrollbar
+ // handling. In some cases webkit reports bad (0)
+ // scrolltop before hiding the element temporary,
+ // sometimes after.
+ scrollvalue = elem.getScrollTop();
+ }
+ // fix another bug where scrollbar remains in wrong
+ // position
+ elem.setScrollTop(scrollvalue - 1);
+ elem.setScrollTop(scrollvalue);
+ }
+
+ // fix for #6940 : Table horizontal scroll sometimes not
+ // updated when collapsing/expanding columns
+ // Also appeared in Safari 5.1 with webkit 534 (#7667)
+ if ((BrowserInfo.get().isChrome() || (BrowserInfo.get()
+ .isSafari() && BrowserInfo.get().getWebkitVersion() >= 534))
+ && (scrollleft > 0 || elem.getScrollLeft() > 0)) {
+ int scrollvalue = scrollleft;
+
+ if (scrollvalue == 0) {
+ // mysterious are the ways of webkits scrollbar
+ // handling. In some cases webkit may report a bad
+ // (0) scrollleft before hiding the element
+ // temporary, sometimes after.
+ scrollvalue = elem.getScrollLeft();
+ }
+ // fix another bug where scrollbar remains in wrong
+ // position
+ elem.setScrollLeft(scrollvalue - 1);
+ elem.setScrollLeft(scrollvalue);
+ }
+ }
+ });
+ }
+
+ }
+
+ public static void alert(String string) {
+ if (true) {
+ Window.alert(string);
+ }
+ }
+
+ /**
+ * Gets the border-box width for the given element, i.e. element width +
+ * border + padding. Always rounds up to nearest integer.
+ *
+ * @param element
+ * The element to check
+ * @return The border-box width for the element
+ */
+ public static int getRequiredWidth(com.google.gwt.dom.client.Element element) {
+ int reqWidth = getRequiredWidthBoundingClientRect(element);
+ if (BrowserInfo.get().isIE() && !BrowserInfo.get().isIE8()) {
+ int csSize = getRequiredWidthComputedStyle(element);
+ if (csSize == reqWidth + 1) {
+ // If computed style reports one pixel larger than requiredWidth
+ // we would be rounding in the wrong direction in IE9. Round up
+ // instead.
+ // We do not always use csSize as it e.g. for 100% wide Labels
+ // in GridLayouts produces senseless values (see e.g.
+ // ThemeTestUI with Runo).
+ return csSize;
+ }
+ }
+ return reqWidth;
+ }
+
+ /**
+ * Gets the border-box height for the given element, i.e. element height +
+ * border + padding. Always rounds up to nearest integer.
+ *
+ * @param element
+ * The element to check
+ * @return The border-box height for the element
+ */
+ public static int getRequiredHeight(
+ com.google.gwt.dom.client.Element element) {
+ int reqHeight = getRequiredHeightBoundingClientRect(element);
+ if (BrowserInfo.get().isIE() && !BrowserInfo.get().isIE8()) {
+ int csSize = getRequiredHeightComputedStyle(element);
+ if (csSize == reqHeight + 1) {
+ // If computed style reports one pixel larger than
+ // requiredHeight we would be rounding in the wrong direction in
+ // IE9. Round up instead.
+ // We do not always use csSize as it e.g. for 100% wide Labels
+ // in GridLayouts produces senseless values (see e.g.
+ // ThemeTestUI with Runo).
+ return csSize;
+ }
+ }
+ return reqHeight;
+ }
+
+ /**
+ * Calculates the width of the element's bounding rectangle.
+ * <p>
+ * In case the browser doesn't support bounding rectangles, the returned
+ * value is the offset width.
+ *
+ * @param element
+ * the element of which to calculate the width
+ * @return the width of the element
+ */
+ public static int getRequiredWidthBoundingClientRect(
+ com.google.gwt.dom.client.Element element) {
+ return (int) Math
+ .ceil(getRequiredWidthBoundingClientRectDouble(element));
+ }
+
+ /**
+ * Calculates the width of the element's bounding rectangle to subpixel
+ * precision.
+ * <p>
+ * In case the browser doesn't support bounding rectangles, the returned
+ * value is the offset width.
+ *
+ * @param element
+ * the element of which to calculate the width
+ * @return the subpixel-accurate width of the element
+ * @since 7.4
+ */
+ public static native double getRequiredWidthBoundingClientRectDouble(
+ com.google.gwt.dom.client.Element element)
+ /*-{
+ if (element.getBoundingClientRect) {
+ var rect = element.getBoundingClientRect();
+ return rect.right - rect.left;
+ } else {
+ return element.offsetWidth;
+ }
+ }-*/;
+
+ public static native int getRequiredHeightComputedStyle(
+ com.google.gwt.dom.client.Element element)
+ /*-{
+ var cs = element.ownerDocument.defaultView.getComputedStyle(element);
+ var heightPx = cs.height;
+ if(heightPx == 'auto'){
+ // Fallback for when IE reports auto
+ heightPx = @com.vaadin.client.WidgetUtil::getRequiredHeightBoundingClientRect(Lcom/google/gwt/dom/client/Element;)(element) + 'px';
+ }
+ var borderTopPx = cs.borderTop;
+ var borderBottomPx = cs.borderBottom;
+ var paddingTopPx = cs.paddingTop;
+ var paddingBottomPx = cs.paddingBottom;
+
+ var height = heightPx.substring(0,heightPx.length-2);
+ var border = borderTopPx.substring(0,borderTopPx.length-2)+borderBottomPx.substring(0,borderBottomPx.length-2);
+ var padding = paddingTopPx.substring(0,paddingTopPx.length-2)+paddingBottomPx.substring(0,paddingBottomPx.length-2);
+ return Math.ceil(height+border+padding);
+ }-*/;
+
+ public static native int getRequiredWidthComputedStyle(
+ com.google.gwt.dom.client.Element element)
+ /*-{
+ var cs = element.ownerDocument.defaultView.getComputedStyle(element);
+ var widthPx = cs.width;
+ if(widthPx == 'auto'){
+ // Fallback for when IE reports auto
+ widthPx = @com.vaadin.client.WidgetUtil::getRequiredWidthBoundingClientRect(Lcom/google/gwt/dom/client/Element;)(element) + 'px';
+ }
+ var borderLeftPx = cs.borderLeft;
+ var borderRightPx = cs.borderRight;
+ var paddingLeftPx = cs.paddingLeft;
+ var paddingRightPx = cs.paddingRight;
+
+ var width = widthPx.substring(0,widthPx.length-2);
+ var border = borderLeftPx.substring(0,borderLeftPx.length-2)+borderRightPx.substring(0,borderRightPx.length-2);
+ var padding = paddingLeftPx.substring(0,paddingLeftPx.length-2)+paddingRightPx.substring(0,paddingRightPx.length-2);
+ return Math.ceil(width+border+padding);
+ }-*/;
+
+ /**
+ * Calculates the height of the element's bounding rectangle.
+ * <p>
+ * In case the browser doesn't support bounding rectangles, the returned
+ * value is the offset height.
+ *
+ * @param element
+ * the element of which to calculate the height
+ * @return the height of the element
+ */
+ public static int getRequiredHeightBoundingClientRect(
+ com.google.gwt.dom.client.Element element) {
+ return (int) Math
+ .ceil(getRequiredHeightBoundingClientRectDouble(element));
+ }
+
+ /**
+ * Calculates the height of the element's bounding rectangle to subpixel
+ * precision.
+ * <p>
+ * In case the browser doesn't support bounding rectangles, the returned
+ * value is the offset height.
+ *
+ * @param element
+ * the element of which to calculate the height
+ * @return the subpixel-accurate height of the element
+ * @since 7.4
+ */
+ public static native double getRequiredHeightBoundingClientRectDouble(
+ com.google.gwt.dom.client.Element element)
+ /*-{
+ var height;
+ if (element.getBoundingClientRect != null) {
+ var rect = element.getBoundingClientRect();
+ height = rect.bottom - rect.top;
+ } else {
+ height = element.offsetHeight;
+ }
+ return height;
+ }-*/;
+
+ public static int getRequiredWidth(Widget widget) {
+ return getRequiredWidth(widget.getElement());
+ }
+
+ public static int getRequiredHeight(Widget widget) {
+ return getRequiredHeight(widget.getElement());
+ }
+
+ /**
+ * Detects what is currently the overflow style attribute in given element.
+ *
+ * @param pe
+ * the element to detect
+ * @return true if auto or scroll
+ */
+ public static boolean mayHaveScrollBars(com.google.gwt.dom.client.Element pe) {
+ String overflow = getComputedStyle(pe, "overflow");
+ if (overflow != null) {
+ if (overflow.equals("auto") || overflow.equals("scroll")) {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * A simple helper method to detect "computed style" (aka style sheets +
+ * element styles). Values returned differ a lot depending on browsers.
+ * Always be very careful when using this.
+ *
+ * @param el
+ * the element from which the style property is detected
+ * @param p
+ * the property to detect
+ * @return String value of style property
+ */
+ private static native String getComputedStyle(
+ com.google.gwt.dom.client.Element el, String p)
+ /*-{
+ try {
+
+ if (el.currentStyle) {
+ // IE
+ return el.currentStyle[p];
+ } else if (window.getComputedStyle) {
+ // Sa, FF, Opera
+ var view = el.ownerDocument.defaultView;
+ return view.getComputedStyle(el,null).getPropertyValue(p);
+ } else {
+ // fall back for non IE, Sa, FF, Opera
+ return "";
+ }
+ } catch (e) {
+ return "";
+ }
+
+ }-*/;
+
+ /**
+ * Will (attempt) to focus the given DOM Element.
+ *
+ * @param el
+ * the element to focus
+ */
+ public static native void focus(Element el)
+ /*-{
+ try {
+ el.focus();
+ } catch (e) {
+
+ }
+ }-*/;
+
+ /**
+ * Helper method to find first instance of given Widget type found by
+ * traversing DOM upwards from given element.
+ * <p>
+ * <strong>Note:</strong> If {@code element} is inside some widget {@code W}
+ * , <em>and</em> {@code W} in turn is wrapped in a {@link Composite}
+ * {@code C}, this method will not find {@code W}. It returns either
+ * {@code C} or null, depending on whether the class parameter matches. This
+ * may also be the case with other Composite-like classes that hijack the
+ * event handling of their child widget(s).
+ *
+ * @param element
+ * the element where to start seeking of Widget
+ * @param class1
+ * the Widget type to seek for
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T findWidget(Element element,
+ Class<? extends Widget> class1) {
+ if (element != null) {
+ /* First seek for the first EventListener (~Widget) from dom */
+ EventListener eventListener = null;
+ while (eventListener == null && element != null) {
+ eventListener = Event.getEventListener(element);
+ if (eventListener == null) {
+ element = element.getParentElement();
+ }
+ }
+ if (eventListener instanceof Widget) {
+ /*
+ * Then find the first widget of type class1 from widget
+ * hierarchy
+ */
+ Widget w = (Widget) eventListener;
+ while (w != null) {
+ if (class1 == null || w.getClass() == class1) {
+ return (T) w;
+ }
+ w = w.getParent();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Force webkit to redraw an element
+ *
+ * @param element
+ * The element that should be redrawn
+ */
+ public static void forceWebkitRedraw(Element element) {
+ Style style = element.getStyle();
+ String s = style.getProperty("webkitTransform");
+ if (s == null || s.length() == 0) {
+ style.setProperty("webkitTransform", "scale(1)");
+ } else {
+ style.setProperty("webkitTransform", "");
+ }
+ }
+
+ /**
+ * Performs a hack to trigger a re-layout in the IE8. This is usually
+ * necessary in cases where IE8 "forgets" to update child elements when they
+ * resize.
+ *
+ * @param e
+ * The element to perform the hack on
+ */
+ public static final void forceIE8Redraw(Element e) {
+ if (BrowserInfo.get().isIE8()) {
+ forceIERedraw(e);
+ }
+ }
+
+ /**
+ * Performs a hack to trigger a re-layout in the IE browser. This is usually
+ * necessary in cases where IE "forgets" to update child elements when they
+ * resize.
+ *
+ * @since 7.3
+ * @param e
+ * The element to perform the hack on
+ */
+ public static void forceIERedraw(Element e) {
+ if (BrowserInfo.get().isIE()) {
+ setStyleTemporarily(e, "zoom", "1");
+ }
+ }
+
+ /**
+ * Detaches and re-attaches the element from its parent. The element is
+ * reattached at the same position in the DOM as it was before.
+ *
+ * Does nothing if the element is not attached to the DOM.
+ *
+ * @param element
+ * The element to detach and re-attach
+ */
+ public static void detachAttach(Element element) {
+ if (element == null) {
+ return;
+ }
+
+ Node nextSibling = element.getNextSibling();
+ Node parent = element.getParentNode();
+ if (parent == null) {
+ return;
+ }
+
+ parent.removeChild(element);
+ if (nextSibling == null) {
+ parent.appendChild(element);
+ } else {
+ parent.insertBefore(element, nextSibling);
+ }
+
+ }
+
+ public static void sinkOnloadForImages(Element element) {
+ NodeList<com.google.gwt.dom.client.Element> imgElements = element
+ .getElementsByTagName("img");
+ for (int i = 0; i < imgElements.getLength(); i++) {
+ DOM.sinkEvents(imgElements.getItem(i), Event.ONLOAD);
+ }
+
+ }
+
+ /**
+ * Returns the index of the childElement within its parent.
+ *
+ * @param subElement
+ * @return
+ */
+ public static int getChildElementIndex(Element childElement) {
+ int idx = 0;
+ Node n = childElement;
+ while ((n = n.getPreviousSibling()) != null) {
+ idx++;
+ }
+
+ return idx;
+ }
+
+ /**
+ * Temporarily sets the {@code styleProperty} to {@code tempValue} and then
+ * resets it to its current value. Used mainly to work around rendering
+ * issues in IE (and possibly in other browsers)
+ *
+ * @param element
+ * The target element
+ * @param styleProperty
+ * The name of the property to set
+ * @param tempValue
+ * The temporary value
+ */
+ public static void setStyleTemporarily(Element element,
+ final String styleProperty, String tempValue) {
+ final Style style = element.getStyle();
+ final String currentValue = style.getProperty(styleProperty);
+
+ style.setProperty(styleProperty, tempValue);
+ element.getOffsetWidth();
+ style.setProperty(styleProperty, currentValue);
+
+ }
+
+ /**
+ * A helper method to return the client position from an event. Returns
+ * position from either first changed touch (if touch event) or from the
+ * event itself.
+ *
+ * @param event
+ * @return
+ */
+ public static int getTouchOrMouseClientX(Event event) {
+ if (isTouchEvent(event)) {
+ return event.getChangedTouches().get(0).getClientX();
+ } else {
+ return event.getClientX();
+ }
+ }
+
+ /**
+ * Find the element corresponding to the coordinates in the passed mouse
+ * event. Please note that this is not always the same as the target of the
+ * event e.g. if event capture is used.
+ *
+ * @param event
+ * the mouse event to get coordinates from
+ * @return the element at the coordinates of the event
+ */
+ public static Element getElementUnderMouse(NativeEvent event) {
+ int pageX = getTouchOrMouseClientX(event);
+ int pageY = getTouchOrMouseClientY(event);
+
+ return getElementFromPoint(pageX, pageY);
+ }
+
+ /**
+ * A helper method to return the client position from an event. Returns
+ * position from either first changed touch (if touch event) or from the
+ * event itself.
+ *
+ * @param event
+ * @return
+ */
+ public static int getTouchOrMouseClientY(Event event) {
+ if (isTouchEvent(event)) {
+ return event.getChangedTouches().get(0).getClientY();
+ } else {
+ return event.getClientY();
+ }
+ }
+
+ /**
+ *
+ * @see #getTouchOrMouseClientY(Event)
+ * @param currentGwtEvent
+ * @return
+ */
+ public static int getTouchOrMouseClientY(NativeEvent currentGwtEvent) {
+ return getTouchOrMouseClientY(Event.as(currentGwtEvent));
+ }
+
+ /**
+ * @see #getTouchOrMouseClientX(Event)
+ *
+ * @param event
+ * @return
+ */
+ public static int getTouchOrMouseClientX(NativeEvent event) {
+ return getTouchOrMouseClientX(Event.as(event));
+ }
+
+ public static boolean isTouchEvent(Event event) {
+ return event.getType().contains("touch");
+ }
+
+ public static boolean isTouchEvent(NativeEvent event) {
+ return isTouchEvent(Event.as(event));
+ }
+
+ public static void simulateClickFromTouchEvent(Event touchevent,
+ Widget widget) {
+ Touch touch = touchevent.getChangedTouches().get(0);
+ final NativeEvent createMouseUpEvent = Document.get()
+ .createMouseUpEvent(0, touch.getScreenX(), touch.getScreenY(),
+ touch.getClientX(), touch.getClientY(), false, false,
+ false, false, NativeEvent.BUTTON_LEFT);
+ final NativeEvent createMouseDownEvent = Document.get()
+ .createMouseDownEvent(0, touch.getScreenX(),
+ touch.getScreenY(), touch.getClientX(),
+ touch.getClientY(), false, false, false, false,
+ NativeEvent.BUTTON_LEFT);
+ final NativeEvent createMouseClickEvent = Document.get()
+ .createClickEvent(0, touch.getScreenX(), touch.getScreenY(),
+ touch.getClientX(), touch.getClientY(), false, false,
+ false, false);
+
+ /*
+ * Get target with element from point as we want the actual element, not
+ * the one that sunk the event.
+ */
+ final Element target = getElementFromPoint(touch.getClientX(),
+ touch.getClientY());
+
+ /*
+ * Fixes infocusable form fields in Safari of iOS 5.x and some Android
+ * browsers.
+ */
+ Widget targetWidget = findWidget(target, null);
+ if (targetWidget instanceof com.google.gwt.user.client.ui.Focusable) {
+ final com.google.gwt.user.client.ui.Focusable toBeFocusedWidget = (com.google.gwt.user.client.ui.Focusable) targetWidget;
+ toBeFocusedWidget.setFocus(true);
+ } else if (targetWidget instanceof Focusable) {
+ ((Focusable) targetWidget).focus();
+ }
+
+ Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+ @Override
+ public void execute() {
+ try {
+ target.dispatchEvent(createMouseDownEvent);
+ target.dispatchEvent(createMouseUpEvent);
+ target.dispatchEvent(createMouseClickEvent);
+ } catch (Exception e) {
+ }
+
+ }
+ });
+
+ }
+
+ /**
+ * Gets the currently focused element.
+ *
+ * @return The active element or null if no active element could be found.
+ */
+ public native static Element getFocusedElement()
+ /*-{
+ if ($wnd.document.activeElement) {
+ return $wnd.document.activeElement;
+ }
+
+ return null;
+ }-*/;
+
+ /**
+ * Gets currently focused element and checks if it's editable
+ *
+ * @since 7.4
+ *
+ * @return true if focused element is editable
+ */
+ public static boolean isFocusedElementEditable() {
+ Element focusedElement = WidgetUtil.getFocusedElement();
+ if (focusedElement != null) {
+ String tagName = focusedElement.getTagName();
+ String contenteditable = focusedElement
+ .getAttribute("contenteditable");
+
+ return "textarea".equalsIgnoreCase(tagName)
+ || "input".equalsIgnoreCase(tagName)
+ || "true".equalsIgnoreCase(contenteditable);
+ }
+ return false;
+ }
+
+ /**
+ * Kind of stronger version of isAttached(). In addition to std isAttached,
+ * this method checks that this widget nor any of its parents is hidden. Can
+ * be e.g used to check whether component should react to some events or
+ * not.
+ *
+ * @param widget
+ * @return true if attached and displayed
+ */
+ public static boolean isAttachedAndDisplayed(Widget widget) {
+ if (widget.isAttached()) {
+ /*
+ * Failfast using offset size, then by iterating the widget tree
+ */
+ boolean notZeroSized = widget.getOffsetHeight() > 0
+ || widget.getOffsetWidth() > 0;
+ return notZeroSized || checkVisibilityRecursively(widget);
+ } else {
+ return false;
+ }
+ }
+
+ private static boolean checkVisibilityRecursively(Widget widget) {
+ if (widget.isVisible()) {
+ Widget parent = widget.getParent();
+ if (parent == null) {
+ return true; // root panel
+ } else {
+ return checkVisibilityRecursively(parent);
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Scrolls an element into view vertically only. Modified version of
+ * Element.scrollIntoView.
+ *
+ * @param elem
+ * The element to scroll into view
+ */
+ public static native void scrollIntoViewVertically(Element elem)
+ /*-{
+ var top = elem.offsetTop;
+ var height = elem.offsetHeight;
+
+ if (elem.parentNode != elem.offsetParent) {
+ top -= elem.parentNode.offsetTop;
+ }
+
+ var cur = elem.parentNode;
+ while (cur && (cur.nodeType == 1)) {
+ if (top < cur.scrollTop) {
+ cur.scrollTop = top;
+ }
+ if (top + height > cur.scrollTop + cur.clientHeight) {
+ cur.scrollTop = (top + height) - cur.clientHeight;
+ }
+
+ var offsetTop = cur.offsetTop;
+ if (cur.parentNode != cur.offsetParent) {
+ offsetTop -= cur.parentNode.offsetTop;
+ }
+
+ top += offsetTop - cur.scrollTop;
+ cur = cur.parentNode;
+ }
+ }-*/;
+
+ /**
+ * Checks if the given event is either a touch event or caused by the left
+ * mouse button
+ *
+ * @param event
+ * @return true if the event is a touch event or caused by the left mouse
+ * button, false otherwise
+ */
+ public static boolean isTouchEventOrLeftMouseButton(Event event) {
+ boolean touchEvent = WidgetUtil.isTouchEvent(event);
+ return touchEvent || event.getButton() == Event.BUTTON_LEFT;
+ }
+
+ /**
+ * Resolve a relative URL to an absolute URL based on the current document's
+ * location.
+ *
+ * @param url
+ * a string with the relative URL to resolve
+ * @return the corresponding absolute URL as a string
+ */
+ public static String getAbsoluteUrl(String url) {
+ if (BrowserInfo.get().isIE8()) {
+ // The hard way - must use innerHTML and attach to DOM in IE8
+ DivElement divElement = Document.get().createDivElement();
+ divElement.getStyle().setDisplay(Display.NONE);
+
+ RootPanel.getBodyElement().appendChild(divElement);
+ divElement.setInnerHTML("<a href='" + escapeAttribute(url)
+ + "' ></a>");
+
+ AnchorElement a = divElement.getChild(0).cast();
+ String href = a.getHref();
+
+ RootPanel.getBodyElement().removeChild(divElement);
+ return href;
+ } else {
+ AnchorElement a = Document.get().createAnchorElement();
+ a.setHref(url);
+ return a.getHref();
+ }
+ }
+
+ /**
+ * Sets the selection range of an input element.
+ *
+ * We need this JSNI function to set selection range so that we can use the
+ * optional direction attribute to set the anchor to the end and the focus
+ * to the start. This makes Firefox work the same way as other browsers
+ * (#13477)
+ *
+ * @param elem
+ * the html input element.
+ * @param pos
+ * the index of the first selected character.
+ * @param length
+ * the selection length.
+ * @param direction
+ * a string indicating the direction in which the selection was
+ * performed. This may be "forward" or "backward", or "none" if
+ * the direction is unknown or irrelevant.
+ *
+ * @since 7.3
+ */
+ public native static void setSelectionRange(Element elem, int pos,
+ int length, String direction)
+ /*-{
+ try {
+ elem.setSelectionRange(pos, pos + length, direction);
+ } catch (e) {
+ // Firefox throws exception if TextBox is not visible, even if attached
+ }
+ }-*/;
+
+ /**
+ * The allowed value inaccuracy when comparing two double-typed pixel
+ * values.
+ * <p>
+ * Since we're comparing pixels on a screen, epsilon must be less than 1.
+ * 0.49 was deemed a perfectly fine and beautifully round number.
+ */
+ public static final double PIXEL_EPSILON = 0.49d;
+
+ /**
+ * Compares two double values with the error margin of
+ * {@link #PIXEL_EPSILON} (i.e. {@value #PIXEL_EPSILON})
+ *
+ * @param num1
+ * the first value for which to compare equality
+ * @param num2
+ * the second value for which to compare equality
+ * @since 7.4
+ *
+ * @return true if the values are considered equals; false otherwise
+ */
+ public static boolean pixelValuesEqual(final double num1, final double num2) {
+ return Math.abs(num1 - num2) <= PIXEL_EPSILON;
+ }
+
+ public static native TextRectangle getBoundingClientRect(Element e)
+ /*-{
+ return e.getBoundingClientRect();
+ }-*/;
+
+ public static final class TextRectangle extends JavaScriptObject {
+ protected TextRectangle() {
+ }
+
+ public native double getBottom()
+ /*-{
+ return this.bottom;
+ }-*/;
+
+ public native double getHeight()
+ /*-{
+ return this.height;
+ }-*/;
+
+ public native double getLeft()
+ /*-{
+ return this.left;
+ }-*/;
+
+ public native double getRight()
+ /*-{
+ return this.right;
+ }-*/;
+
+ public native double getTop()
+ /*-{
+ return this.top;
+ }-*/;
+
+ public native double getWidth()
+ /*-{
+ return this.width;
+ }-*/;
+ }
+
+ /**
+ * Wrap a css size value and its unit and translate back and forth to the
+ * string representation.<br/>
+ * Eg. 50%, 123px, ...
+ *
+ * @since 7.2.6
+ * @author Vaadin Ltd
+ */
+ @SuppressWarnings("serial")
+ public static class CssSize implements Serializable {
+
+ /*
+ * Map the size units with their type.
+ */
+ private static Map<String, Unit> type2Unit = new HashMap<String, Style.Unit>();
+ static {
+ for (Unit unit : Unit.values()) {
+ type2Unit.put(unit.getType(), unit);
+ }
+ }
+
+ /**
+ * Gets the unit value by its type.
+ *
+ * @param type
+ * the type of the unit as found in the style.
+ * @return the unit value.
+ */
+ public static Unit unitByType(String type) {
+ return type2Unit.get(type);
+ }
+
+ /*
+ * Regex to parse the size.
+ */
+ private static final RegExp sizePattern = RegExp
+ .compile(SharedUtil.SIZE_PATTERN);
+
+ /**
+ * Parse the size from string format to {@link CssSize}.
+ *
+ * @param s
+ * the size as string.
+ * @return a {@link CssSize} object.
+ */
+ public static CssSize fromString(String s) {
+ if (s == null) {
+ return null;
+ }
+
+ s = s.trim();
+ if ("".equals(s)) {
+ return null;
+ }
+
+ float size = 0;
+ Unit unit = null;
+
+ MatchResult matcher = sizePattern.exec(s);
+ if (matcher.getGroupCount() > 1) {
+
+ size = Float.parseFloat(matcher.getGroup(1));
+ if (size < 0) {
+ size = -1;
+ unit = Unit.PX;
+
+ } else {
+ String symbol = matcher.getGroup(2);
+ unit = unitByType(symbol);
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid size argument: \""
+ + s + "\" (should match " + sizePattern.getSource()
+ + ")");
+ }
+ return new CssSize(size, unit);
+ }
+
+ /**
+ * Creates a {@link CssSize} using a value and its measurement unit.
+ *
+ * @param value
+ * the value.
+ * @param unit
+ * the unit.
+ * @return the {@link CssSize} object.
+ */
+ public static CssSize fromValueUnit(float value, Unit unit) {
+ return new CssSize(value, unit);
+ }
+
+ /*
+ * The value.
+ */
+ private final float value;
+
+ /*
+ * The measure unit.
+ */
+ private final Unit unit;
+
+ private CssSize(float value, Unit unit) {
+ this.value = value;
+ this.unit = unit;
+ }
+
+ /**
+ * Gets the value for this css size.
+ *
+ * @return the value.
+ */
+ public float getValue() {
+ return value;
+ }
+
+ /**
+ * Gets the measurement unit for this css size.
+ *
+ * @return the unit.
+ */
+ public Unit getUnit() {
+ return unit;
+ }
+
+ @Override
+ public String toString() {
+ return value + unit.getType();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof CssSize) {
+ CssSize size = (CssSize) obj;
+ return size.value == value && size.unit == unit;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check whether the two sizes are equals.
+ *
+ * @param cssSize1
+ * the first size to compare.
+ * @param cssSize2
+ * the other size to compare with the first one.
+ * @return true if the two sizes are equals, otherwise false.
+ */
+ public static boolean equals(String cssSize1, String cssSize2) {
+ return CssSize.fromString(cssSize1).equals(
+ CssSize.fromString(cssSize2));
+ }
+
+ }
+
+ private static Logger getLogger() {
+ return Logger.getLogger(WidgetUtil.class.getName());
+ }
+
+}
diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java
index 2b8ffec2d7..5a48455ae3 100644
--- a/client/src/com/vaadin/client/ui/VScrollTable.java
+++ b/client/src/com/vaadin/client/ui/VScrollTable.java
@@ -25,6 +25,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
@@ -47,8 +49,6 @@ import com.google.gwt.dom.client.TableSectionElement;
import com.google.gwt.dom.client.Touch;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
-import com.google.gwt.event.dom.client.ContextMenuEvent;
-import com.google.gwt.event.dom.client.ContextMenuHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
@@ -68,6 +68,8 @@ import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
@@ -88,6 +90,7 @@ import com.vaadin.client.UIDL;
import com.vaadin.client.Util;
import com.vaadin.client.VConsole;
import com.vaadin.client.VTooltip;
+import com.vaadin.client.WidgetUtil;
import com.vaadin.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
import com.vaadin.client.ui.dd.DDUtil;
import com.vaadin.client.ui.dd.VAbstractDropHandler;
@@ -128,6 +131,137 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable,
ActionOwner, SubPartAware {
+ /**
+ * Simple interface for parts of the table capable of owning a context menu.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+ private interface ContextMenuOwner {
+ public void showContextMenu(Event event);
+ }
+
+ /**
+ * Handles showing context menu on "long press" from a touch screen.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+ private class TouchContextProvider {
+ private static final int TOUCH_CONTEXT_MENU_TIMEOUT = 500;
+ private Timer contextTouchTimeout;
+
+ private Event touchStart;
+ private int touchStartY;
+ private int touchStartX;
+
+ private ContextMenuOwner target;
+
+ /**
+ * Initializes a handler for a certain context menu owner.
+ *
+ * @param target
+ * the owner of the context menu
+ */
+ public TouchContextProvider(ContextMenuOwner target) {
+ this.target = target;
+ }
+
+ /**
+ * Cancels the current context touch timeout.
+ */
+ public void cancel() {
+ if (contextTouchTimeout != null) {
+ contextTouchTimeout.cancel();
+ contextTouchTimeout = null;
+ }
+ touchStart = null;
+ }
+
+ /**
+ * A function to handle touch context events in a table.
+ *
+ * @param event
+ * browser event to handle
+ */
+ public void handleTouchEvent(final Event event) {
+ int type = event.getTypeInt();
+
+ switch (type) {
+ case Event.ONCONTEXTMENU:
+ target.showContextMenu(event);
+ break;
+ case Event.ONTOUCHSTART:
+ // save position to fields, touches in events are same
+ // instance during the operation.
+ touchStart = event;
+
+ Touch touch = event.getChangedTouches().get(0);
+ touchStartX = touch.getClientX();
+ touchStartY = touch.getClientY();
+
+ if (contextTouchTimeout == null) {
+ contextTouchTimeout = new Timer() {
+
+ @Override
+ public void run() {
+ if (touchStart != null) {
+ // Open the context menu if finger
+ // is held in place long enough.
+ target.showContextMenu(touchStart);
+ event.preventDefault();
+ touchStart = null;
+ }
+ }
+ };
+ }
+ contextTouchTimeout.schedule(TOUCH_CONTEXT_MENU_TIMEOUT);
+ break;
+ case Event.ONTOUCHCANCEL:
+ case Event.ONTOUCHEND:
+ cancel();
+ break;
+ case Event.ONTOUCHMOVE:
+ if (isSignificantMove(event)) {
+ // Moved finger before the context menu timer
+ // expired, so let the browser handle the event.
+ cancel();
+ }
+ }
+ }
+
+ /**
+ * Calculates how many pixels away the user's finger has traveled. This
+ * reduces the chance of small non-intentional movements from canceling
+ * the long press detection.
+ *
+ * @param event
+ * the Event for which to check the move distance
+ * @return true if this is considered an intentional move by the user
+ */
+ protected boolean isSignificantMove(Event event) {
+ if (touchStart == null) {
+ // no touch start
+ return false;
+ }
+
+ // Calculate the distance between touch start and the current touch
+ // position
+ Touch touch = event.getChangedTouches().get(0);
+ int deltaX = touch.getClientX() - touchStartX;
+ int deltaY = touch.getClientY() - touchStartY;
+ int delta = deltaX * deltaX + deltaY * deltaY;
+
+ // Compare to the square of the significant move threshold to remove
+ // the need for a square root
+ if (delta > TouchScrollDelegate.SIGNIFICANT_MOVE_THRESHOLD
+ * TouchScrollDelegate.SIGNIFICANT_MOVE_THRESHOLD) {
+ return true;
+ }
+ return false;
+ }
+ }
+
public static final String STYLENAME = "v-table";
public enum SelectMode {
@@ -195,6 +329,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/** For internal use only. May be removed or replaced in the future. */
public boolean immediate;
+ private boolean updatedReqRows = true;
+
private boolean nullSelectionAllowed = true;
private SelectMode selectMode = SelectMode.NONE;
@@ -369,8 +505,49 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
/** For internal use only. May be removed or replaced in the future. */
public final TableFooter tFoot = new TableFooter();
+ /** Handles context menu for table body */
+ private ContextMenuOwner contextMenuOwner = new ContextMenuOwner() {
+
+ @Override
+ public void showContextMenu(Event event) {
+ int left = WidgetUtil.getTouchOrMouseClientX(event);
+ int top = WidgetUtil.getTouchOrMouseClientY(event);
+ boolean menuShown = handleBodyContextMenu(left, top);
+ if (menuShown) {
+ event.stopPropagation();
+ event.preventDefault();
+ }
+ }
+ };
+
+ /** Handles touch events to display a context menu for table body */
+ private TouchContextProvider touchContextProvider = new TouchContextProvider(
+ contextMenuOwner);
+
+ /**
+ * For internal use only. May be removed or replaced in the future.
+ *
+ * Overwrites onBrowserEvent function on FocusableScrollPanel to give event
+ * access to touchContextProvider. Has to be public to give TableConnector
+ * access to the scrollBodyPanel field.
+ *
+ * @since 7.2
+ * @author Vaadin Ltd
+ */
+ public class FocusableScrollContextPanel extends FocusableScrollPanel {
+ @Override
+ public void onBrowserEvent(Event event) {
+ super.onBrowserEvent(event);
+ touchContextProvider.handleTouchEvent(event);
+ };
+
+ public FocusableScrollContextPanel(boolean useFakeFocusElement) {
+ super(useFakeFocusElement);
+ }
+ }
+
/** For internal use only. May be removed or replaced in the future. */
- public final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(
+ public final FocusableScrollContextPanel scrollBodyPanel = new FocusableScrollContextPanel(
true);
private KeyPressHandler navKeyPressHandler = new KeyPressHandler() {
@@ -590,6 +767,51 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private HandlerRegistration addCloseHandler;
+ /**
+ * Changes to manage mouseDown and mouseUp
+ */
+ /**
+ * The element where the last mouse down event was registered.
+ */
+ private Element lastMouseDownTarget;
+
+ /**
+ * Set to true by {@link #mouseUpPreviewHandler} if it gets a mouseup at the
+ * same element as {@link #lastMouseDownTarget}.
+ */
+ private boolean mouseUpPreviewMatched = false;
+
+ private HandlerRegistration mouseUpEventPreviewRegistration;
+
+ /**
+ * Previews events after a mousedown to detect where the following mouseup
+ * hits.
+ */
+ private final NativePreviewHandler mouseUpPreviewHandler = new NativePreviewHandler() {
+
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ if (event.getTypeInt() == Event.ONMOUSEUP) {
+ mouseUpEventPreviewRegistration.removeHandler();
+
+ // Event's reported target not always correct if event
+ // capture is in use
+ Element elementUnderMouse = WidgetUtil
+ .getElementUnderMouse(event.getNativeEvent());
+ if (lastMouseDownTarget != null
+ && lastMouseDownTarget.isOrHasChild(elementUnderMouse)) {
+ mouseUpPreviewMatched = true;
+ } else {
+ getLogger().log(
+ Level.FINEST,
+ "Ignoring mouseup from " + elementUnderMouse
+ + " when mousedown was on "
+ + lastMouseDownTarget);
+ }
+ }
+ }
+ };
+
public VScrollTable() {
setMultiSelectMode(MULTISELECT_MODE_DEFAULT);
@@ -610,16 +832,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
scrollBodyPanel.addKeyUpHandler(navKeyUpHandler);
- scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS);
-
- scrollBodyPanel.sinkEvents(Event.ONCONTEXTMENU);
- scrollBodyPanel.addDomHandler(new ContextMenuHandler() {
-
- @Override
- public void onContextMenu(ContextMenuEvent event) {
- handleBodyContextMenu(event);
- }
- }, ContextMenuEvent.getType());
+ scrollBodyPanel.sinkEvents(Event.TOUCHEVENTS | Event.ONCONTEXTMENU);
setStyleName(STYLENAME);
@@ -681,19 +894,23 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
});
}
- private void handleBodyContextMenu(ContextMenuEvent event) {
+ /**
+ * Handles a context menu event on table body.
+ *
+ * @param left
+ * left position of the context menu
+ * @param top
+ * top position of the context menu
+ * @return true if a context menu was shown, otherwise false
+ */
+ private boolean handleBodyContextMenu(int left, int top) {
if (enabled && bodyActionKeys != null) {
- int left = Util.getTouchOrMouseClientX(event.getNativeEvent());
- int top = Util.getTouchOrMouseClientY(event.getNativeEvent());
top += Window.getScrollTop();
left += Window.getScrollLeft();
client.getContextMenu().showAt(this, left, top);
-
- // Only prevent browser context menu if there are action handlers
- // registered
- event.stopPropagation();
- event.preventDefault();
+ return true;
}
+ return false;
}
/**
@@ -838,6 +1055,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
sendSelectedRows(immediate);
}
+ private void updateFirstVisibleAndSendSelectedRows() {
+ updateFirstVisibleRow();
+ sendSelectedRows(immediate);
+ }
+
/**
* Sends the selection to the server if it has been changed since the last
* update/visit.
@@ -1002,7 +1224,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Without this call the scroll position is messed up in IE even after
// the lazy scroller has set the scroll position to the first visible
// item
- scrollBodyPanel.getScrollPosition();
+ int pos = scrollBodyPanel.getScrollPosition();
+
+ // Reset first row in view port so client requests correct last row.
+ if (pos == 0) {
+ firstRowInViewPort = 0;
+ }
scrollBody = createScrollBody();
@@ -1085,25 +1312,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
selected = true;
keyboardSelectionOverRowFetchInProgress = true;
}
- if (selected) {
-
- if (focusedRow == null
- || !selectedRowKeys.contains(focusedRow
- .getKey())) {
- /*
- * The focus is no longer on a selected row. Move
- * focus to the selected row. (#10522)
- *
- * Don't do this for multiselect (#13341).
- *
- * Checking the selection mode here instead of in
- * setRowFocus allows keyboard shift+downarrow
- * selection to work as expected.
- */
-
- setRowFocus(row);
- }
+ if (selected && selectedKeys.size() == 1) {
+ /*
+ * If a single item is selected, move focus to the
+ * selected row. (#10522)
+ */
+ setRowFocus(row);
}
+
if (selected != row.isSelected()) {
row.toggleSelection();
@@ -1183,7 +1399,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void execute() {
- if (firstvisible > 0) {
+ if (firstvisible >= 0) {
firstRowInViewPort = firstvisible;
if (firstvisibleOnLastPage > -1) {
scrollBodyPanel
@@ -1992,6 +2208,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
final FooterCell fCell = (FooterCell) footCells.next();
boolean needsIndent = hierarchyColumnIndent > 0
&& hCell.isHierarchyColumn();
+ hCell.saveNaturalColumnWidthIfNotSaved(i);
+ fCell.saveNaturalColumnWidthIfNotSaved(i);
int w = hCell.getWidth();
if (hCell.isDefinedWidth()) {
// server has defined column width explicitly
@@ -2017,8 +2235,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int footerWidth = fCell.getNaturalColumnWidth(i);
w = headerWidth > footerWidth ? headerWidth : footerWidth;
}
- hCell.setNaturalMinimumColumnWidth(w);
- fCell.setNaturalMinimumColumnWidth(w);
+ if (w != 0) {
+ hCell.setNaturalMinimumColumnWidth(w);
+ fCell.setNaturalMinimumColumnWidth(w);
+ }
}
widths[i] = w;
total += w;
@@ -2038,7 +2258,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int w = total;
w += scrollBody.getCellExtraWidth() * visibleColOrder.length;
if (willHaveScrollbarz) {
- w += Util.getNativeScrollbarSize();
+ w += WidgetUtil.getNativeScrollbarSize();
}
setContentWidth(w);
}
@@ -2051,7 +2271,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
availW -= scrollBody.getCellExtraWidth() * visibleColOrder.length;
if (willHaveScrollbarz) {
- availW -= Util.getNativeScrollbarSize();
+ availW -= WidgetUtil.getNativeScrollbarSize();
}
// TODO refactor this code to be the same as in resize timer
@@ -2223,10 +2443,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
boolean needsSpaceForHorizontalSrollbar = (total > availW);
if (needsSpaceForHorizontalSrollbar) {
- bodyHeight += Util.getNativeScrollbarSize();
+ bodyHeight += WidgetUtil.getNativeScrollbarSize();
}
scrollBodyPanel.setHeight(bodyHeight + "px");
- Util.runWebkitOverflowAutoFix(scrollBodyPanel.getElement());
+ WidgetUtil.runWebkitOverflowAutoFix(scrollBodyPanel.getElement());
}
isNewBody = false;
@@ -2257,7 +2477,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* Ensures the column alignments are correct at initial loading. <br/>
* (child components widths are correct)
*/
- Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement());
+ WidgetUtil.runWebkitOverflowAutoFixDeferred(scrollBodyPanel
+ .getElement());
hadScrollBars = willHaveScrollbarz;
}
@@ -2394,10 +2615,33 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public void run() {
+
if (client.hasActiveRequest() || navKeyDown) {
// if client connection is busy, don't bother loading it more
VConsole.log("Postponed rowfetch");
schedule(250);
+ } else if (allRenderedRowsAreNew() && !updatedReqRows) {
+
+ /*
+ * If all rows are new, there might have been a server-side call
+ * to Table.setCurrentPageFirstItemIndex(int) In this case,
+ * scrolling event takes way too late, and all the rows from
+ * previous viewport to this one were requested.
+ *
+ * This should prevent requesting unneeded rows by updating
+ * reqFirstRow and reqRows before needing them. See (#14135)
+ */
+
+ setReqFirstRow((firstRowInViewPort - (int) (pageLength * cache_rate)));
+ int last = firstRowInViewPort + (int) (cache_rate * pageLength)
+ + pageLength - 1;
+ if (last >= totalRows) {
+ last = totalRows - 1;
+ }
+ setReqRows(last - getReqFirstRow() + 1);
+ updatedReqRows = true;
+ schedule(250);
+
} else {
int firstRendered = scrollBody.getFirstRendered();
@@ -2485,6 +2729,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
client.updateVariable(paintableId, "firstvisible",
firstRowInViewPort, false);
}
+
client.updateVariable(paintableId, "reqfirstrow", reqFirstRow,
false);
client.updateVariable(paintableId, "reqrows", reqRows, true);
@@ -2715,6 +2960,10 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
+ private void setUndefinedWidthFlagOnly() {
+ definedWidth = false;
+ }
+
/**
* Detects if width is fixed by developer on server side or resized to
* current width by user.
@@ -2888,7 +3137,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
case Event.ONTOUCHSTART:
case Event.ONMOUSEDOWN:
if (columnReordering
- && Util.isTouchEventOrLeftMouseButton(event)) {
+ && WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHSTART) {
/*
* prevent using this event in e.g. scrolling
@@ -2908,9 +3157,18 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
if (columnReordering
- && Util.isTouchEventOrLeftMouseButton(event)) {
+ && WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
dragging = false;
DOM.releaseCapture(getElement());
+
+ if (WidgetUtil.isTouchEvent(event)) {
+ /*
+ * Prevent using in e.g. scrolling and prevent generated
+ * events.
+ */
+ event.preventDefault();
+ event.stopPropagation();
+ }
if (moved) {
hideFloatingCopy();
tHead.removeSlotFocus();
@@ -2922,20 +3180,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
reOrderColumn(cid, closestSlot);
}
}
- }
- if (Util.isTouchEvent(event)) {
- /*
- * Prevent using in e.g. scrolling and prevent generated
- * events.
- */
- event.preventDefault();
- event.stopPropagation();
+ moved = false;
+ break;
}
}
if (!moved) {
// mouse event was a click to header -> sort column
- if (sortable && Util.isTouchEventOrLeftMouseButton(event)) {
+ if (sortable
+ && WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
if (sortColumn.equals(cid)) {
// just toggle order
client.updateVariable(paintableId, "sortascending",
@@ -2957,7 +3210,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
rowRequestHandler.run(); // run immediately
}
fireHeaderClickedEvent(event);
- if (Util.isTouchEvent(event)) {
+ if (WidgetUtil.isTouchEvent(event)) {
/*
* Prevent using in e.g. scrolling and prevent generated
* events.
@@ -2973,7 +3226,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
break;
case Event.ONTOUCHMOVE:
case Event.ONMOUSEMOVE:
- if (dragging && Util.isTouchEventOrLeftMouseButton(event)) {
+ if (dragging && WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
if (event.getTypeInt() == Event.ONTOUCHMOVE) {
/*
* prevent using this event in e.g. scrolling
@@ -2985,7 +3238,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
moved = true;
}
- final int clientX = Util.getTouchOrMouseClientX(event);
+ final int clientX = WidgetUtil
+ .getTouchOrMouseClientX(event);
final int x = clientX + tHead.hTableWrapper.getScrollLeft();
int slotX = headerX;
closestSlot = colIndex;
@@ -3023,7 +3277,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private void onResizeEvent(Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONMOUSEDOWN:
- if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ if (!WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
return;
}
isResizing = true;
@@ -3034,7 +3288,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
DOM.eventPreventDefault(event);
break;
case Event.ONMOUSEUP:
- if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ if (!WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
return;
}
isResizing = false;
@@ -3051,7 +3305,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
fireColumnResizeEvent(cid, originalWidth, getColWidth(cid));
break;
case Event.ONMOUSEMOVE:
- if (!Util.isTouchEventOrLeftMouseButton(event)) {
+ if (!WidgetUtil.isTouchEventOrLeftMouseButton(event)) {
return;
}
if (isResizing) {
@@ -3129,6 +3383,34 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
/**
+ * Saves natural column width if it hasn't been saved already.
+ *
+ * @param columnIndex
+ * @since 7.3.9
+ */
+ protected void saveNaturalColumnWidthIfNotSaved(int columnIndex) {
+ if (naturalWidth < 0) {
+ // This is recently revealed column. Try to detect a proper
+ // value (greater of header and data columns)
+
+ int hw = captionContainer.getOffsetWidth() + getHeaderPadding();
+ if (BrowserInfo.get().isGecko()) {
+ hw += sortIndicator.getOffsetWidth();
+ }
+ if (columnIndex < 0) {
+ columnIndex = 0;
+ for (Iterator<Widget> it = tHead.iterator(); it.hasNext(); columnIndex++) {
+ if (it.next() == this) {
+ break;
+ }
+ }
+ }
+ final int cw = scrollBody.getColWidth(columnIndex);
+ naturalWidth = (hw > cw ? hw : cw);
+ }
+ }
+
+ /**
* Detects the natural minimum width for the column of this header cell.
* If column is resized by user or the width is defined by server the
* actual width is returned. Else the natural min width is returned.
@@ -3141,33 +3423,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public int getNaturalColumnWidth(int columnIndex) {
final int iw = columnIndex == getHierarchyColumnIndex() ? scrollBody
.getMaxIndent() : 0;
+ saveNaturalColumnWidthIfNotSaved(columnIndex);
if (isDefinedWidth()) {
if (iw > width) {
return iw;
}
return width;
} else {
- if (naturalWidth < 0) {
- // This is recently revealed column. Try to detect a proper
- // value (greater of header and data columns)
-
- int hw = captionContainer.getOffsetWidth()
- + getHeaderPadding();
- if (BrowserInfo.get().isGecko()) {
- hw += sortIndicator.getOffsetWidth();
- }
- if (columnIndex < 0) {
- columnIndex = 0;
- for (Iterator<Widget> it = tHead.iterator(); it
- .hasNext(); columnIndex++) {
- if (it.next() == this) {
- break;
- }
- }
- }
- final int cw = scrollBody.getColWidth(columnIndex);
- naturalWidth = (hw > cw ? hw : cw);
- }
if (iw > naturalWidth) {
// indent is temporary value, naturalWidth shouldn't be
// updated
@@ -3354,9 +3616,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
c.setText(caption);
}
+ c.setSorted(false);
if (col.hasAttribute("sortable")) {
c.setSortable(true);
- c.setSorted(false);
} else {
c.setSortable(false);
}
@@ -3404,7 +3666,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
} else if (col.hasAttribute("er")) {
c.setExpandRatio(col.getFloatAttribute("er"));
-
+ c.setUndefinedWidthFlagOnly();
} else if (recalcWidths) {
c.setUndefinedWidth();
@@ -3978,7 +4240,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
/**
- * Returns the expand ration of the cell
+ * Returns the expand ratio of the cell
*
* @return The expand ratio
*/
@@ -4063,6 +4325,32 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
/**
+ * Saves natural column width if it hasn't been saved already.
+ *
+ * @param columnIndex
+ * @since 7.3.9
+ */
+ protected void saveNaturalColumnWidthIfNotSaved(int columnIndex) {
+ if (naturalWidth < 0) {
+ // This is recently revealed column. Try to detect a proper
+ // value (greater of header and data cols)
+
+ final int hw = ((Element) getElement().getLastChild())
+ .getOffsetWidth() + getHeaderPadding();
+ if (columnIndex < 0) {
+ columnIndex = 0;
+ for (Iterator<Widget> it = tHead.iterator(); it.hasNext(); columnIndex++) {
+ if (it.next() == this) {
+ break;
+ }
+ }
+ }
+ final int cw = scrollBody.getColWidth(columnIndex);
+ naturalWidth = (hw > cw ? hw : cw);
+ }
+ }
+
+ /**
* Detects the natural minimum width for the column of this header cell.
* If column is resized by user or the width is defined by server the
* actual width is returned. Else the natural min width is returned.
@@ -4075,31 +4363,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public int getNaturalColumnWidth(int columnIndex) {
final int iw = columnIndex == getHierarchyColumnIndex() ? scrollBody
.getMaxIndent() : 0;
+ saveNaturalColumnWidthIfNotSaved(columnIndex);
if (isDefinedWidth()) {
if (iw > width) {
return iw;
}
return width;
} else {
- if (naturalWidth < 0) {
- // This is recently revealed column. Try to detect a proper
- // value (greater of header and data
- // cols)
-
- final int hw = ((Element) getElement().getLastChild())
- .getOffsetWidth() + getHeaderPadding();
- if (columnIndex < 0) {
- columnIndex = 0;
- for (Iterator<Widget> it = tHead.iterator(); it
- .hasNext(); columnIndex++) {
- if (it.next() == this) {
- break;
- }
- }
- }
- final int cw = scrollBody.getColWidth(columnIndex);
- naturalWidth = (hw > cw ? hw : cw);
- }
if (iw > naturalWidth) {
return iw;
} else {
@@ -4466,10 +4736,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
public int getLastRendered() {
+
return lastRendered;
}
public int getFirstRendered() {
+
return firstRendered;
}
@@ -4487,7 +4759,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
*/
public int getRequiredHeight() {
return preSpacer.getOffsetHeight() + postSpacer.getOffsetHeight()
- + Util.getRequiredHeight(table);
+ + WidgetUtil.getRequiredHeight(table);
}
private void constructDOM() {
@@ -4553,10 +4825,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
} else if (firstIndex + rows == firstRendered) {
final VScrollTableRow[] rowArray = new VScrollTableRow[rows];
int i = rows;
+
while (it.hasNext()) {
i--;
rowArray[i] = prepareRow((UIDL) it.next());
}
+
for (i = 0; i < rows; i++) {
addRowBeforeFirstRendered(rowArray[i]);
firstRendered--;
@@ -4581,10 +4855,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
setLastRendered(lastRendered + 1);
setContainerHeight();
fixSpacers();
+
while (it.hasNext()) {
addRow(prepareRow((UIDL) it.next()));
setLastRendered(lastRendered + 1);
}
+
fixSpacers();
}
@@ -4599,6 +4875,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* has changed since the last request.
*/
protected void ensureCacheFilled() {
+
+ /**
+ * Fixes cache issue #13576 where unnecessary rows are fetched
+ */
+ if (isLazyScrollerActive()) {
+ return;
+ }
+
int reactFirstRow = (int) (firstRowInViewPort - pageLength
* cache_react_rate);
int reactLastRow = (int) (firstRowInViewPort + pageLength + pageLength
@@ -5118,7 +5402,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return -1;
}
- public class VScrollTableRow extends Panel implements ActionOwner {
+ public class VScrollTableRow extends Panel implements ActionOwner,
+ ContextMenuOwner {
private static final int TOUCHSCROLL_TIMEOUT = 100;
private static final int DRAGMODE_MULTIROW = 2;
@@ -5136,10 +5421,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
private Timer dragTouchTimeout;
private int touchStartY;
private int touchStartX;
+
+ private TouchContextProvider touchContextProvider = new TouchContextProvider(
+ this);
+
private TooltipInfo tooltipInfo = null;
private Map<TableCellElement, TooltipInfo> cellToolTips = new HashMap<TableCellElement, TooltipInfo>();
private boolean isDragging = false;
private String rowStyle = null;
+ protected boolean applyZeroWidthFix = true;
private VScrollTableRow(int rowKey) {
this.rowKey = rowKey;
@@ -5245,7 +5535,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* definition of zero width table cells. Instead, use 1px
* and compensate with a negative margin.
*/
- if (width == 0) {
+ if (applyZeroWidthFix && width == 0) {
wrapperWidth = 1;
wrapperStyle.setMarginRight(-1, Unit.PX);
} else {
@@ -5591,6 +5881,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
boolean touchEventHandled = false;
if (enabled && hasNativeTouchScrolling) {
+ touchContextProvider.handleTouchEvent(event);
+
final Element targetTdOrTr = getEventTargetTdOrTr(event);
final int type = event.getTypeInt();
@@ -5681,8 +5973,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (!BrowserInfo.get().isAndroid()) {
event.preventDefault();
event.stopPropagation();
- Util.simulateClickFromTouchEvent(touchStart,
- this);
+ WidgetUtil.simulateClickFromTouchEvent(
+ touchStart, this);
}
touchStart = null;
}
@@ -5732,114 +6024,134 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
break;
case Event.ONMOUSEUP:
- if (targetCellOrRowFound) {
- /*
- * Queue here, send at the same time as the
- * corresponding value change event - see #7127
- */
- boolean clickEventSent = handleClickEvent(event,
- targetTdOrTr, false);
-
- if (event.getButton() == Event.BUTTON_LEFT
- && isSelectable()) {
-
- // Ctrl+Shift click
- if ((event.getCtrlKey() || event.getMetaKey())
- && event.getShiftKey()
- && isMultiSelectModeDefault()) {
- toggleShiftSelection(false);
- setRowFocus(this);
-
- // Ctrl click
- } else if ((event.getCtrlKey() || event
- .getMetaKey())
- && isMultiSelectModeDefault()) {
- boolean wasSelected = isSelected();
- toggleSelection();
- setRowFocus(this);
- /*
- * next possible range select must start on
- * this row
- */
- selectionRangeStart = this;
- if (wasSelected) {
- removeRowFromUnsentSelectionRanges(this);
- }
+ /*
+ * Only fire a click if the mouseup hits the same
+ * element as the corresponding mousedown. This is first
+ * checked in the event preview but we can't fire the
+ * event there as the event might get canceled before it
+ * gets here.
+ */
+ if (mouseUpPreviewMatched
+ && lastMouseDownTarget != null
+ && lastMouseDownTarget == getElementTdOrTr(WidgetUtil
+ .getElementUnderMouse(event))) {
+ // "Click" with left, right or middle button
+
+ if (targetCellOrRowFound) {
+ /*
+ * Queue here, send at the same time as the
+ * corresponding value change event - see #7127
+ */
+ boolean clickEventSent = handleClickEvent(
+ event, targetTdOrTr, false);
+
+ if (event.getButton() == Event.BUTTON_LEFT
+ && isSelectable()) {
+
+ // Ctrl+Shift click
+ if ((event.getCtrlKey() || event
+ .getMetaKey())
+ && event.getShiftKey()
+ && isMultiSelectModeDefault()) {
+ toggleShiftSelection(false);
+ setRowFocus(this);
- } else if ((event.getCtrlKey() || event
- .getMetaKey()) && isSingleSelectMode()) {
- // Ctrl (or meta) click (Single selection)
- if (!isSelected()
- || (isSelected() && nullSelectionAllowed)) {
+ // Ctrl click
+ } else if ((event.getCtrlKey() || event
+ .getMetaKey())
+ && isMultiSelectModeDefault()) {
+ boolean wasSelected = isSelected();
+ toggleSelection();
+ setRowFocus(this);
+ /*
+ * next possible range select must start
+ * on this row
+ */
+ selectionRangeStart = this;
+ if (wasSelected) {
+ removeRowFromUnsentSelectionRanges(this);
+ }
- if (!isSelected()) {
- deselectAll();
+ } else if ((event.getCtrlKey() || event
+ .getMetaKey())
+ && isSingleSelectMode()) {
+ // Ctrl (or meta) click (Single
+ // selection)
+ if (!isSelected()
+ || (isSelected() && nullSelectionAllowed)) {
+
+ if (!isSelected()) {
+ deselectAll();
+ }
+
+ toggleSelection();
+ setRowFocus(this);
}
- toggleSelection();
+ } else if (event.getShiftKey()
+ && isMultiSelectModeDefault()) {
+ // Shift click
+ toggleShiftSelection(true);
+
+ } else {
+ // click
+ boolean currentlyJustThisRowSelected = selectedRowKeys
+ .size() == 1
+ && selectedRowKeys
+ .contains(getKey());
+
+ if (!currentlyJustThisRowSelected) {
+ if (isSingleSelectMode()
+ || isMultiSelectModeDefault()) {
+ /*
+ * For default multi select mode
+ * (ctrl/shift) and for single
+ * select mode we need to clear
+ * the previous selection before
+ * selecting a new one when the
+ * user clicks on a row. Only in
+ * multiselect/simple mode the
+ * old selection should remain
+ * after a normal click.
+ */
+ deselectAll();
+ }
+ toggleSelection();
+ } else if ((isSingleSelectMode() || isMultiSelectModeSimple())
+ && nullSelectionAllowed) {
+ toggleSelection();
+ }/*
+ * else NOP to avoid excessive server
+ * visits (selection is removed with
+ * CTRL/META click)
+ */
+
+ selectionRangeStart = this;
setRowFocus(this);
}
- } else if (event.getShiftKey()
- && isMultiSelectModeDefault()) {
- // Shift click
- toggleShiftSelection(true);
-
- } else {
- // click
- boolean currentlyJustThisRowSelected = selectedRowKeys
- .size() == 1
- && selectedRowKeys
- .contains(getKey());
-
- if (!currentlyJustThisRowSelected) {
- if (isSingleSelectMode()
- || isMultiSelectModeDefault()) {
- /*
- * For default multi select mode
- * (ctrl/shift) and for single
- * select mode we need to clear the
- * previous selection before
- * selecting a new one when the user
- * clicks on a row. Only in
- * multiselect/simple mode the old
- * selection should remain after a
- * normal click.
- */
- deselectAll();
- }
- toggleSelection();
- } else if ((isSingleSelectMode() || isMultiSelectModeSimple())
- && nullSelectionAllowed) {
- toggleSelection();
- }/*
- * else NOP to avoid excessive server
- * visits (selection is removed with
- * CTRL/META click)
- */
-
- selectionRangeStart = this;
- setRowFocus(this);
+ // Remove IE text selection hack
+ if (BrowserInfo.get().isIE()) {
+ ((Element) event.getEventTarget()
+ .cast()).setPropertyJSO(
+ "onselectstart", null);
+ }
+ // Queue value change
+ sendSelectedRows(false);
}
-
- // Remove IE text selection hack
- if (BrowserInfo.get().isIE()) {
- ((Element) event.getEventTarget().cast())
- .setPropertyJSO("onselectstart",
- null);
+ /*
+ * Send queued click and value change events if
+ * any If a click event is sent, send value
+ * change with it regardless of the immediate
+ * flag, see #7127
+ */
+ if (immediate || clickEventSent) {
+ client.sendPendingVariableChanges();
}
- // Queue value change
- sendSelectedRows(false);
- }
- /*
- * Send queued click and value change events if any
- * If a click event is sent, send value change with
- * it regardless of the immediate flag, see #7127
- */
- if (immediate || clickEventSent) {
- client.sendPendingVariableChanges();
}
}
+ mouseUpPreviewMatched = false;
+ lastMouseDownTarget = null;
break;
case Event.ONTOUCHEND:
case Event.ONTOUCHCANCEL:
@@ -5848,12 +6160,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* Touch has not been handled as neither context or
* drag start, handle it as a click.
*/
- Util.simulateClickFromTouchEvent(touchStart, this);
+ WidgetUtil.simulateClickFromTouchEvent(touchStart,
+ this);
touchStart = null;
}
- if (contextTouchTimeout != null) {
- contextTouchTimeout.cancel();
- }
+ touchContextProvider.cancel();
break;
case Event.ONTOUCHMOVE:
if (isSignificantMove(event)) {
@@ -5868,9 +6179,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.getActiveScrollDelegate() == null)) {
startRowDrag(touchStart, type, targetTdOrTr);
}
- if (contextTouchTimeout != null) {
- contextTouchTimeout.cancel();
- }
+ touchContextProvider.cancel();
/*
* Avoid clicks and drags by clearing touch start
* flag.
@@ -5883,7 +6192,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
touchStart = event;
Touch touch = event.getChangedTouches().get(0);
// save position to fields, touches in events are same
- // isntance during the operation.
+ // instance during the operation.
touchStartX = touch.getClientX();
touchStartY = touch.getClientY();
/*
@@ -5949,6 +6258,17 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
break;
case Event.ONMOUSEDOWN:
+ /*
+ * When getting a mousedown event, we must detect where
+ * the corresponding mouseup event if it's on a
+ * different part of the page.
+ */
+ lastMouseDownTarget = getElementTdOrTr(WidgetUtil
+ .getElementUnderMouse(event));
+ mouseUpPreviewMatched = false;
+ mouseUpEventPreviewRegistration = Event
+ .addNativePreviewHandler(mouseUpPreviewHandler);
+
if (targetCellOrRowFound) {
setRowFocus(this);
ensureFocus();
@@ -6083,7 +6403,12 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
*/
private Element getEventTargetTdOrTr(Event event) {
final Element eventTarget = event.getEventTarget().cast();
- Widget widget = Util.findWidget(eventTarget, null);
+ return getElementTdOrTr(eventTarget);
+ }
+
+ private Element getElementTdOrTr(Element element) {
+
+ Widget widget = WidgetUtil.findWidget(element, null);
if (widget != this) {
/*
@@ -6103,15 +6428,16 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return null;
}
}
- return getTdOrTr(eventTarget);
+ return getTdOrTr(element);
}
+ @Override
public void showContextMenu(Event event) {
if (enabled && actionKeys != null) {
// Show context menu if there are registered action handlers
- int left = Util.getTouchOrMouseClientX(event)
+ int left = WidgetUtil.getTouchOrMouseClientX(event)
+ Window.getScrollLeft();
- int top = Util.getTouchOrMouseClientY(event)
+ int top = WidgetUtil.getTouchOrMouseClientY(event)
+ Window.getScrollTop();
showContextMenu(left, top);
}
@@ -6172,9 +6498,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
VScrollTableRow startRow = selectionRangeStart;
if (startRow == null) {
startRow = focusedRow;
+ selectionRangeStart = focusedRow;
// If start row is null then we have a multipage selection
- // from
- // above
+ // from above
if (startRow == null) {
startRow = (VScrollTableRow) scrollBody.iterator()
.next();
@@ -6390,8 +6716,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.getVisibleCellCount(); ix++) {
spanWidth += tHead.getHeaderCell(ix).getOffsetWidth();
}
- Util.setWidthExcludingPaddingAndBorder((Element) getElement()
- .getChild(cellIx), spanWidth, 13, false);
+ WidgetUtil.setWidthExcludingPaddingAndBorder(
+ (Element) getElement().getChild(cellIx), spanWidth, 13,
+ false);
}
}
@@ -6565,6 +6892,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// natural width already includes indent if any
int naturalColumnWidth = hCell
.getNaturalColumnWidth(colIndex);
+ /*
+ * TODO If there is extra width, expand ratios are for
+ * additional extra widths, not for absolute column widths.
+ * Should be fixed in sizeInit(), too.
+ */
+ if (hCell.getExpandRatio() > 0) {
+ naturalColumnWidth = 0;
+ }
usedMinimumWidth += naturalColumnWidth;
expandRatioDivider += hCell.getExpandRatio();
if (hasIndent) {
@@ -6581,8 +6916,17 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int totalExtraWidth = scrollBody.getCellExtraWidth()
* visibleCellCount;
if (willHaveScrollbars()) {
- totalExtraWidth += Util.getNativeScrollbarSize();
+ totalExtraWidth += WidgetUtil.getNativeScrollbarSize();
+ // if there will be vertical scrollbar, let's enable it
+ scrollBodyPanel.getElement().getStyle().clearOverflowY();
+ } else {
+ // if there is no need for vertical scrollbar, let's disable it
+ // this is necessary since sometimes the browsers insist showing
+ // the scrollbar even if the content would fit perfectly
+ scrollBodyPanel.getElement().getStyle()
+ .setOverflowY(Overflow.HIDDEN);
}
+
availW -= totalExtraWidth;
int forceScrollBodyWidth = -1;
@@ -6600,6 +6944,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
forceScrollBodyWidth = usedMinimumWidth + totalExtraWidth;
}
extraSpace = 0;
+ // if there will be horizontal scrollbar, let's enable it
+ scrollBodyPanel.getElement().getStyle().clearOverflowX();
+ } else {
+ // if there is no need for horizontal scrollbar, let's disable
+ // it
+ // this is necessary since sometimes the browsers insist showing
+ // the scrollbar even if the content would fit perfectly
+ scrollBodyPanel.getElement().getStyle()
+ .setOverflowX(Overflow.HIDDEN);
}
if (forceScrollBodyWidth > 0) {
@@ -6651,6 +7004,9 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int newSpace;
if (expandRatioDivider > 0) {
// divide excess space by expand ratios
+ if (hCell.getExpandRatio() > 0) {
+ w = 0;
+ }
newSpace = Math.round((w + extraSpace
* hCell.getExpandRatio() / expandRatioDivider));
} else {
@@ -6696,7 +7052,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
colIndex = 0;
while (headCells.hasNext()) {
HeaderCell hc = (HeaderCell) headCells.next();
- if (!hc.isDefinedWidth()) {
+ if (!hc.isResizing && !hc.isDefinedWidth()) {
setColWidth(colIndex, hc.getWidthWithIndent() + availW
- checksum, false);
break;
@@ -6711,7 +7067,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
int bodyHeight = scrollBody.getRequiredHeight();
boolean needsSpaceForHorizontalScrollbar = (availW < usedMinimumWidth);
if (needsSpaceForHorizontalScrollbar) {
- bodyHeight += Util.getNativeScrollbarSize();
+ bodyHeight += WidgetUtil.getNativeScrollbarSize();
}
int heightBefore = getOffsetHeight();
scrollBodyPanel.setHeight(bodyHeight + "px");
@@ -6721,8 +7077,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
- Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement());
-
forceRealignColumnHeaders();
}
@@ -6758,7 +7112,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
*/
private int getBorderWidth() {
if (borderWidth < 0) {
- borderWidth = Util.measureHorizontalPaddingAndBorder(
+ borderWidth = WidgetUtil.measureHorizontalPaddingAndBorder(
scrollBodyPanel.getElement(), 2);
if (borderWidth < 0) {
borderWidth = 0;
@@ -6851,15 +7205,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (initializedAndAttached) {
updatePageLength();
}
- if (!rendering) {
- // Webkit may sometimes get an odd rendering bug (white space
- // between header and body), see bug #3875. Running
- // overflow hack here to shake body element a bit.
- // We must run the fix as a deferred command to prevent it from
- // overwriting the scroll position with an outdated value, see
- // #7607.
- Util.runWebkitOverflowAutoFixDeferred(scrollBodyPanel.getElement());
- }
triggerLazyColumnAdjustment(false);
@@ -6914,6 +7259,20 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return s;
}
+ // Updates first visible row for the case we cannot wait
+ // for onScroll
+ private void updateFirstVisibleRow() {
+ scrollTop = scrollBodyPanel.getScrollPosition();
+ firstRowInViewPort = calcFirstRowInViewPort();
+ int maxFirstRow = totalRows - pageLength;
+ if (firstRowInViewPort > maxFirstRow && maxFirstRow >= 0) {
+ firstRowInViewPort = maxFirstRow;
+ }
+ lastRequestedFirstvisible = firstRowInViewPort;
+ client.updateVariable(paintableId, "firstvisible", firstRowInViewPort,
+ false);
+ }
+
/**
* This method has logic which rows needs to be requested from server when
* user scrolls
@@ -7003,8 +7362,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
return;
}
- if (firstRowInViewPort - pageLength * cache_rate > lastRendered
- || firstRowInViewPort + pageLength + pageLength * cache_rate < firstRendered) {
+ if (allRenderedRowsAreNew()) {
// need a totally new set of rows
rowRequestHandler
.setReqFirstRow((firstRowInViewPort - (int) (pageLength * cache_rate)));
@@ -7015,11 +7373,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
rowRequestHandler.setReqRows(last
- rowRequestHandler.getReqFirstRow() + 1);
+ updatedReqRows = false;
rowRequestHandler.deferRowFetch();
return;
}
if (preLimit < firstRendered) {
// need some rows to the beginning of the rendered area
+
rowRequestHandler
.setReqFirstRow((int) (firstRowInViewPort - pageLength
* cache_rate));
@@ -7037,6 +7397,14 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
}
+ private boolean allRenderedRowsAreNew() {
+ int firstRowInViewPort = calcFirstRowInViewPort();
+ int firstRendered = scrollBody.getFirstRendered();
+ int lastRendered = scrollBody.getLastRendered();
+ return (firstRowInViewPort - pageLength * cache_rate > lastRendered || firstRowInViewPort
+ + pageLength + pageLength * cache_rate < firstRendered);
+ }
+
protected int calcFirstRowInViewPort() {
return (int) Math.ceil(scrollTop / scrollBody.getRowHeight());
}
@@ -7087,7 +7455,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
Class<? extends Widget> clazz = getRowClass();
VScrollTableRow row = null;
if (clazz != null) {
- row = Util.findWidget(elementOver, clazz);
+ row = WidgetUtil.findWidget(elementOver, clazz);
}
if (row != null) {
dropDetails.overkey = row.rowKey;
@@ -7240,7 +7608,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
if (row != null) {
-
// Apply focus style to new selection
row.addStyleName(getStylePrimaryName() + "-focus");
@@ -7254,12 +7621,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// Set new focused row
focusedRow = row;
- /*
- * Don't scroll to the focused row when in multiselect mode.
- * (#13341)
- */
-
- if (isSingleSelectMode()) {
+ if (hasFocus) {
ensureRowIsVisible(row);
}
@@ -7281,7 +7643,11 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// get odd scrolling here.
return;
}
- Util.scrollIntoViewVertically(row.getElement());
+ /*
+ * FIXME The next line doesn't always do what expected, because if the
+ * row is not in the DOM it won't scroll to it.
+ */
+ WidgetUtil.scrollIntoViewVertically(row.getElement());
}
/**
@@ -7375,7 +7741,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// focus and select the last visible row
setRowFocus(lastVisibleRowInViewPort);
selectFocusedRow(ctrl, shift);
- sendSelectedRows();
+ updateFirstVisibleAndSendSelectedRows();
} else {
int indexOfToBeFocused = focusedRow.getIndex()
+ getFullyVisibleRowCount();
@@ -7392,20 +7758,20 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
setRowFocus(toBeFocusedRow);
selectFocusedRow(ctrl, shift);
// TODO needs scrollintoview ?
- sendSelectedRows();
+ updateFirstVisibleAndSendSelectedRows();
} else {
// scroll down by pixels and return, to wait for
// new rows, then select the last item in the
// viewport
selectLastItemInNextRender = true;
multiselectPending = shift;
- scrollByPagelenght(1);
+ scrollByPagelength(1);
}
}
}
} else {
/* No selections, go page down by scrolling */
- scrollByPagelenght(1);
+ scrollByPagelength(1);
}
return true;
}
@@ -7428,7 +7794,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// focus and select the first visible row
setRowFocus(firstVisibleRowInViewPort);
selectFocusedRow(ctrl, shift);
- sendSelectedRows();
+ updateFirstVisibleAndSendSelectedRows();
} else {
int indexOfToBeFocused = focusedRow.getIndex()
- getFullyVisibleRowCount();
@@ -7443,7 +7809,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
setRowFocus(toBeFocusedRow);
selectFocusedRow(ctrl, shift);
// TODO needs scrollintoview ?
- sendSelectedRows();
+ updateFirstVisibleAndSendSelectedRows();
} else {
// unless waiting for the next rowset already
// scroll down by pixels and return, to wait for
@@ -7451,13 +7817,13 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
// viewport
selectFirstItemInNextRender = true;
multiselectPending = shift;
- scrollByPagelenght(-1);
+ scrollByPagelength(-1);
}
}
}
} else {
/* No selections, go page up by scrolling */
- scrollByPagelenght(-1);
+ scrollByPagelength(-1);
}
return true;
@@ -7475,7 +7841,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (rowByRowIndex.getIndex() == 0) {
setRowFocus(rowByRowIndex);
selectFocusedRow(ctrl, shift);
- sendSelectedRows();
+ updateFirstVisibleAndSendSelectedRows();
} else {
// first row of table will come in next row fetch
if (ctrl) {
@@ -7501,7 +7867,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
if (focusedRow != rowByRowIndex) {
setRowFocus(rowByRowIndex);
selectFocusedRow(ctrl, shift);
- sendSelectedRows();
+ updateFirstVisibleAndSendSelectedRows();
}
} else {
if (ctrl) {
@@ -7531,7 +7897,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
.getRowHeight());
}
- private void scrollByPagelenght(int i) {
+ private void scrollByPagelength(int i) {
int pixels = i * scrollBodyPanel.getOffsetHeight();
int newPixels = scrollBodyPanel.getScrollPosition() + pixels;
if (newPixels < 0) {
@@ -7582,7 +7948,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
* ...and sometimes it sends blur events even though the focus
* handler is still active. (#10464)
*/
- Element focusedElement = Util.getIEFocusedElement();
+ Element focusedElement = WidgetUtil.getFocusedElement();
if (Util.getConnectorForElement(client, getParent(), focusedElement) == this
&& focusedElement != null
&& focusedElement != scrollBodyPanel.getFocusElement()) {
@@ -7735,7 +8101,6 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
public void lazyRevertFocusToRow(final VScrollTableRow currentlyFocusedRow) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
-
@Override
public void execute() {
if (currentlyFocusedRow != null) {
@@ -7892,7 +8257,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
@Override
public String getSubPartName(com.google.gwt.user.client.Element subElement) {
- Widget widget = Util.findWidget(subElement, null);
+ Widget widget = WidgetUtil.findWidget(subElement, null);
if (widget instanceof HeaderCell) {
return SUBPART_HEADER + "[" + tHead.visibleCells.indexOf(widget)
+ "]";
@@ -7923,11 +8288,15 @@ public class VScrollTable extends FlowPanel implements HasWidgets,
}
/**
- * @since
+ * @since 7.2.6
*/
public void onUnregister() {
if (addCloseHandler != null) {
addCloseHandler.removeHandler();
}
}
+
+ private static Logger getLogger() {
+ return Logger.getLogger(VScrollTable.class.getName());
+ }
}
diff --git a/ivysettings.xml b/ivysettings.xml
index 981ef2006d..e27dd95c12 100644
--- a/ivysettings.xml
+++ b/ivysettings.xml
@@ -27,6 +27,10 @@
<modules>
<module organisation="com.vaadin" name="vaadin-testbench"
resolver="vaadin-addons" />
+ <module organisation="com.vaadin" name="vaadin-testbench-core"
+ resolver="vaadin-addons" />
+ <module organisation="com.vaadin" name="vaadin-testbench-api"
+ resolver="vaadin-addons" />
<module organisation="com.vaadin" name="vaadin-buildhelpers"
resolver="build-temp" />
<module organisation="com.vaadin" name="vaadin-shared"
diff --git a/uitest/integration_tests.xml b/uitest/integration_tests.xml
index c0d73580bb..716523eab0 100644
--- a/uitest/integration_tests.xml
+++ b/uitest/integration_tests.xml
@@ -27,7 +27,9 @@
<!-- Base url where the testable application is deployed -->
<property name="deployment.url" value="http://${test.integration.server}:8080" />
-
+ <!-- TestBench license parameter -->
+ <property name="vaadin.testbench.developer.license" value="" />
+
<property name="report.dir" location="${integration_test.dir}/result/reports-integration" />
<!-- ssh host values -->
@@ -124,6 +126,7 @@
<jvmarg value="-Dserver-name=${server-name}" />
<jvmarg value="-Djava.awt.headless=true" />
<jvmarg value="-Ddemo.war=${demo.war}" />
+ <jvmarg value="-Dvaadin.testbench.developer.license=${vaadin.testbench.developer.license}" />
<test name="${junit.test.suite}" todir="${server.report.dir}" />
</junit>
</target>
diff --git a/uitest/ivy.xml b/uitest/ivy.xml
index 020543c53f..d33bffaf78 100644
--- a/uitest/ivy.xml
+++ b/uitest/ivy.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ivy-module [
- <!ENTITY jetty.version "8.1.9.v20130131">
+ <!ENTITY jetty.version "8.1.12.v20130726">
]>
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -71,11 +71,17 @@
</dependency>
<!-- jetty-servlets needed by ProxyTest, but not by jetty-runner -->
<dependency org="org.eclipse.jetty" name="jetty-servlets"
- rev="&jetty.version;" conf="ide, build-provided, jetty-run->default" />
+ rev="&jetty.version;" conf="ide, build-provided, jetty-run->default" >
+ <exclude org="org.eclipse.jetty.orbit"></exclude>
+ </dependency>
<dependency org="org.eclipse.jetty" name="jetty-websocket"
- rev="&jetty.version;" conf="ide, jetty-run->default" />
+ rev="&jetty.version;" conf="ide, jetty-run->default">
+ <exclude org="org.eclipse.jetty.orbit"></exclude>
+ </dependency>
<dependency org="org.eclipse.jetty" name="jetty-webapp"
- rev="&jetty.version;" conf="ide, build-provided, jetty-run->default" />
+ rev="&jetty.version;" conf="ide, build-provided, jetty-run->default">
+ <exclude org="org.eclipse.jetty.orbit"></exclude>
+ </dependency>
<dependency org="org.mortbay.jetty" name="jetty-runner"
rev="&jetty.version;" conf="ide, jetty-run->default">
<exclude org="org.eclipse.jetty.orbit"></exclude>
@@ -95,10 +101,20 @@
<dependency org="org.hsqldb" name="hsqldb" rev="2.2.6"
conf="build,ide -> default" />
<dependency org="com.vaadin" name="vaadin-testbench"
- rev="4.0.0.alpha1" conf="build-provided,ide -> default" />
+ rev="4.0.2" conf="build-provided,ide -> default" />
<!-- This should be removed once tests have been updated to use lang3 -->
<dependency org="commons-lang" name="commons-lang"
- rev="2.6" conf="build,ide -> default" />
+ rev="2.6" conf="build,ide -> default" />
+ <!--<dependency org="com.vaadin" name="vaadin-sass-compiler"
+ rev="${vaadin.sass.version}" conf="compile-theme->default" />
+
+ <dependency org="com.vaadin" name="vaadin-buildhelpers"
+ rev="${vaadin.version}" conf="compile-theme->build" /> -->
+
+ <dependency org="org.eclipse.jgit" name="org.eclipse.jgit"
+ rev="3.5.1.201410131835-r" conf="ide,build->default">
+ <exclude org="org.apache.httpcomponents"></exclude>
+ </dependency>
</dependencies>
</ivy-module>
diff --git a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java
index 43d6a55a8b..f2d8ef8a52 100644
--- a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java
+++ b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -22,6 +22,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class VerifyBrowserVersionTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java b/uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java
index 8dfcf52b75..d15a5e28ce 100644
--- a/uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java
+++ b/uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java
@@ -7,6 +7,7 @@ import org.junit.Test;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class ActionsOnInvisibleComponentsTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java
index 5a815fb40c..014808fe27 100644
--- a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java
+++ b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -23,6 +23,7 @@ import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class NoApplicationClassTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java b/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java
index 4f5c16218e..98150e959b 100644
--- a/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java
+++ b/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -25,12 +25,13 @@ import org.junit.Test;
import org.openqa.selenium.WebElement;
import com.vaadin.testbench.By;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
* Test to see if AbstractOrderedLayout displays captions correctly with
* expanding ratios.
- *
+ *
* @author Vaadin Ltd
*/
public class AbstractOrderedLayoutWithCaptionsTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java
index f664149cce..bac7d6b401 100644
--- a/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java
+++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarResizeOverlappingEventsTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -26,10 +26,11 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
- *
+ *
* @author Vaadin Ltd
*/
public class CalendarResizeOverlappingEventsTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java
index 7951187fa7..b847ae66d2 100644
--- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java
+++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -25,6 +25,7 @@ import org.openqa.selenium.interactions.Actions;
import com.vaadin.testbench.By;
import com.vaadin.testbench.commands.TestBenchElementCommands;
import com.vaadin.testbench.elements.ComboBoxElement;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
diff --git a/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java b/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java
index a57017746a..5d299ac12b 100644
--- a/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java
+++ b/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -27,6 +27,7 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class DisabledDateFieldPopupTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java b/uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java
index a9e7a1bca7..e34c5a3398 100644
--- a/uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java
+++ b/uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -27,10 +27,11 @@ import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
- *
+ *
* @since
* @author Vaadin Ltd
*/
@@ -38,7 +39,7 @@ public class JavaScriptPreloadingTest extends MultiBrowserTest {
/*
* (non-Javadoc)
- *
+ *
* @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest()
*/
@Override
diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java
index 3cfe30a991..4a7f2fa548 100644
--- a/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java
+++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -30,11 +30,12 @@ import org.openqa.selenium.internal.Locatable;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.elements.MenuBarElement;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
* Test to see if tooltips will render in the correct locations near the edges.
- *
+ *
* @author Vaadin Ltd
*/
public class MenuBarTooltipsNearEdgeTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java b/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java
index eb838c135e..d274f7104b 100644
--- a/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java
+++ b/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -26,10 +26,11 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
- *
+ *
* @since
* @author Vaadin Ltd
*/
@@ -38,7 +39,7 @@ public class NativeSelectsAndChromeKeyboardNavigationTest extends
/*
* (non-Javadoc)
- *
+ *
* @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest()
*/
@Override
@@ -74,7 +75,7 @@ public class NativeSelectsAndChromeKeyboardNavigationTest extends
/*
* (non-Javadoc)
- *
+ *
* @see com.vaadin.tests.tb3.AbstractTB3Test#getUIClass()
*/
@Override
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java
index a95ceca22b..86368f194c 100644
--- a/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -19,6 +19,7 @@ import org.junit.Test;
import org.openqa.selenium.By;
import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class CaptionLeakTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java
index 1afcabec1d..2469d8a204 100644
--- a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java
+++ b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -24,6 +24,7 @@ import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.By;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class VerticalLayoutFocusWithDOMChangesTest extends MultiBrowserTest {
@@ -54,8 +55,8 @@ public class VerticalLayoutFocusWithDOMChangesTest extends MultiBrowserTest {
Assert.assertEquals("Just a button", activeElement.getText());
DesiredCapabilities capabilities = getDesiredCapabilities();
- if (capabilities.equals(BrowserUtil.ie(8))
- || capabilities.equals(BrowserUtil.ie(9))) {
+ if (capabilities.equals(BrowserUtil.ie8())
+ || capabilities.equals(BrowserUtil.ie9())) {
// IE8 and IE9 insert cursor in the start of input instead of end.
Assert.assertEquals(incrementalText + initialText,
tf1.getAttribute("value"));
@@ -86,8 +87,8 @@ public class VerticalLayoutFocusWithDOMChangesTest extends MultiBrowserTest {
new Actions(getDriver()).sendKeys(secondText).build().perform();
DesiredCapabilities capabilities = getDesiredCapabilities();
- if (capabilities.equals(BrowserUtil.ie(8))
- || capabilities.equals(BrowserUtil.ie(9))) {
+ if (capabilities.equals(BrowserUtil.ie8())
+ || capabilities.equals(BrowserUtil.ie9())) {
// IE8 and IE9 insert cursor in the start of input instead of end.
Assert.assertEquals(secondText + firstText,
tf2.getAttribute("value"));
diff --git a/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java
index 897511e41a..f533929d08 100644
--- a/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java
+++ b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -29,6 +29,7 @@ import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.By;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class AddSelectionToRemovedRangeTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java b/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java
index 255a798594..6d9a831c6d 100644
--- a/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java
+++ b/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -25,6 +25,7 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class CtrlShiftMultiselectTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java
index b4b8d93fbe..16e8bc21da 100644
--- a/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java
+++ b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java
@@ -24,11 +24,11 @@ import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
+import com.vaadin.testbench.annotations.RunLocally;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.elements.TableElement;
-import com.vaadin.tests.tb3.AbstractTB3Test.RunLocally;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
/**
* Test case creating and deleting table component in a loop, testing memory
diff --git a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java
index 0fc09adf40..41c25d7d93 100644
--- a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java
+++ b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -31,6 +31,7 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class SelectAllRowsTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java b/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java
index 6aae1e27fc..2fbc4ad6ef 100644
--- a/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java
+++ b/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -24,6 +24,7 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class TableWithPollingTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java
index 12ae03080b..87032e59ed 100644
--- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java
+++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -27,6 +27,7 @@ import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.By;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class TabSheetFocusedTabTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java
index fca312ba7e..b00450852e 100644
--- a/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java
+++ b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -25,6 +25,7 @@ import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.elements.TextAreaElement;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class TextAreaEventPropagationModifierKeysTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java b/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java
index ae966a5b07..ebc6883dcc 100644
--- a/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java
+++ b/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -34,6 +34,7 @@ import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebElement;
import com.vaadin.testbench.elements.UploadElement;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class TestFileUploadTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java
index 335590437d..88e08192aa 100644
--- a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java
+++ b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -27,12 +27,13 @@ import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.tb3.MultiBrowserTest;
/**
* Test for issue #12726, IE's make text selection when sub windows are
* dragged(moved).
- *
+ *
* @since
* @author Vaadin Ltd
*/
@@ -56,9 +57,9 @@ public class SubWindowsTextSelectionTest extends MultiBrowserTest {
@Override
public List<DesiredCapabilities> getBrowsersToTest() {
ArrayList<DesiredCapabilities> list = new ArrayList<DesiredCapabilities>();
- list.add(BrowserUtil.ie(9));
- list.add(BrowserUtil.ie(10));
- list.add(BrowserUtil.ie(11));
+ list.add(BrowserUtil.ie9());
+ list.add(BrowserUtil.ie10());
+ list.add(BrowserUtil.ie11());
return list;
}
diff --git a/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java b/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java
index 073975a509..844f0e9c29 100644
--- a/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java
+++ b/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -15,14 +15,14 @@
*/
package com.vaadin.tests.integration;
+import com.vaadin.testbench.parallel.TestNameSuffix;
import com.vaadin.tests.tb3.PrivateTB3Configuration;
-import com.vaadin.tests.tb3.TestNameSuffix;
/**
* Base class for integration tests. Integration tests use the
* {@literal deployment.url} parameter to determine the base deployment url
* (http://hostname:123)
- *
+ *
* @author Vaadin Ltd
*/
@TestNameSuffix(property = "server-name")
diff --git a/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java b/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java
index bfe38b8865..5ac31007b3 100644
--- a/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java
+++ b/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -23,6 +23,7 @@ import org.junit.Test;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
import com.vaadin.tests.tb3.MultiBrowserTest;
public class IE8MeasuredSizeMemoryLeakTest extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java b/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java
index 093ee348b8..51612882e4 100644
--- a/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/BasicPushWebsocketTest.java
@@ -1,29 +1,29 @@
-/*
- * 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.List;
-
-import org.openqa.selenium.remote.DesiredCapabilities;
-
-import com.vaadin.tests.tb3.WebsocketTest;
-
-public class BasicPushWebsocketTest extends BasicPushTest {
- @Override
- public List<DesiredCapabilities> getBrowsersToTest() {
- return WebsocketTest.getWebsocketBrowsers();
- }
-}
+///*
+// * 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.List;
+//
+//import org.openqa.selenium.remote.DesiredCapabilities;
+//
+//import com.vaadin.tests.tb3.WebsocketTest;
+//
+//public class BasicPushWebsocketTest extends BasicPushTest {
+// @Override
+// public List<DesiredCapabilities> getBrowsersToTest() {
+// return WebsocketTest.getBrowsersToTest();
+// }
+// }
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java
index 06ddc07abb..b1727a02fe 100644
--- a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -36,7 +36,7 @@ public abstract class ExtremelyLongPushTimeTest extends MultiBrowserTest {
testBench(driver).disableWaitForVaadin();
// Wait for startButton to be present
- waitForElementToBePresent(vaadinLocatorById("startButton"));
+ waitForElementPresent(vaadinLocatorById("startButton"));
String logRow0Id = "Log_row_0";
By logRow0 = vaadinLocatorById(logRow0Id);
diff --git a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java
index c0b188bbab..0f6d08d595 100644
--- a/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/ExtremelyLongPushTimeWebsocketTest.java
@@ -1,31 +1,31 @@
-/*
- * 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.List;
-
-import org.openqa.selenium.remote.DesiredCapabilities;
-
-import com.vaadin.tests.tb3.WebsocketTest;
-
-public class ExtremelyLongPushTimeWebsocketTest extends
- ExtremelyLongPushTimeTest {
-
- @Override
- public List<DesiredCapabilities> getBrowsersToTest() {
- return WebsocketTest.getWebsocketBrowsers();
- }
-}
+///*
+// * 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.List;
+//
+//import org.openqa.selenium.remote.DesiredCapabilities;
+//
+//import com.vaadin.tests.tb3.WebsocketTest;
+//
+//public class ExtremelyLongPushTimeWebsocketTest extends
+// ExtremelyLongPushTimeTest {
+//
+// @Override
+// public List<DesiredCapabilities> getBrowsersToTest() {
+// return WebsocketTest.getWebsocketBrowsers();
+// }
+// }
diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java
index 644dbd7580..0e1d1d6231 100644
--- a/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelWebsocketTest.java
@@ -1,35 +1,35 @@
-/*
- * 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.List;
-
-import org.openqa.selenium.remote.DesiredCapabilities;
-
-import com.vaadin.tests.tb3.WebsocketTest;
-
-public class IdlePushChannelWebsocketTest extends IdlePushChannelTest {
-
- @Override
- protected Class<?> getUIClass() {
- return BasicPushWebsocket.class;
- }
-
- @Override
- public List<DesiredCapabilities> getBrowsersToTest() {
- return WebsocketTest.getWebsocketBrowsers();
- }
-}
+///*
+// * 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.List;
+//
+//import org.openqa.selenium.remote.DesiredCapabilities;
+//
+//import com.vaadin.tests.tb3.WebsocketTest;
+//
+//public class IdlePushChannelWebsocketTest extends IdlePushChannelTest {
+//
+// @Override
+// protected Class<?> getUIClass() {
+// return BasicPushWebsocket.class;
+// }
+//
+// @Override
+// public List<DesiredCapabilities> getBrowsersToTest() {
+// return WebsocketTest.getWebsocketBrowsers();
+// }
+// }
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java
index ac58deea56..73f6fc1e1a 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationLongPollingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -24,6 +24,8 @@ import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.Select;
+import com.vaadin.testbench.parallel.Browser;
+
public class PushConfigurationLongPollingTest extends PushConfigurationTest {
@Override
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java
index 8dc960c9ac..91c4f5a2a7 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationStreamingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -25,6 +25,8 @@ import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.Select;
+import com.vaadin.testbench.parallel.Browser;
+
public class PushConfigurationStreamingTest extends PushConfigurationTest {
@Override
diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java
index c9a813fac0..a464fa20b2 100644
--- a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -25,6 +25,8 @@ import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.Select;
+import com.vaadin.testbench.parallel.Browser;
+
public class PushConfigurationWebSocketTest extends PushConfigurationTest {
@Override
diff --git a/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java b/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java
index 1f6e181c89..3865443201 100644
--- a/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -21,6 +21,7 @@ import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.tests.annotations.TestCategory;
import com.vaadin.tests.tb3.MultiBrowserTest;
diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java
index 00ee6bae25..91c2606f08 100644
--- a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -42,7 +42,7 @@ public class PushLargeDataLongPollingTest extends MultiBrowserTest {
private void push() throws InterruptedException {
// Wait for startButton to be present
- waitForElementToBePresent(vaadinLocatorById("startButton"));
+ waitForElementPresent(vaadinLocatorById("startButton"));
String logRow0Id = "Log_row_0";
By logRow0 = vaadinLocatorById(logRow0Id);
diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java
index 26fa512ab2..e43bef3e7f 100644
--- a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -42,7 +42,7 @@ public class PushLargeDataStreamingTest extends MultiBrowserTest {
private void push() throws InterruptedException {
// Wait for startButton to be present
- waitForElementToBePresent(vaadinLocatorById("startButton"));
+ waitForElementPresent(vaadinLocatorById("startButton"));
String logRow0Id = "Log_row_0";
By logRow0 = vaadinLocatorById(logRow0Id);
diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java
index 57fb8c33b0..d1c11192d5 100644
--- a/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/PushLargeDataWebsocketTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -40,7 +40,7 @@ public class PushLargeDataWebsocketTest extends WebsocketTest {
private void push() throws Exception {
// Wait for startButton to be present
- waitForElementToBePresent(vaadinLocatorById("startButton"));
+ waitForElementPresent(vaadinLocatorById("startButton"));
String logRow0Id = "Log_row_0";
By logRow0 = vaadinLocatorById(logRow0Id);
diff --git a/uitest/src/com/vaadin/tests/push/ReconnectTest.java b/uitest/src/com/vaadin/tests/push/ReconnectTest.java
index 5ad2e7a127..5f5789d4ca 100644
--- a/uitest/src/com/vaadin/tests/push/ReconnectTest.java
+++ b/uitest/src/com/vaadin/tests/push/ReconnectTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -83,7 +83,8 @@ public abstract class ReconnectTest extends MultiBrowserTestWithProxy {
waitForDebugMessage("Reopening push connection");
}
- private void clearDebugMessages() {
+ @Override
+ protected void clearDebugMessages() {
driver.findElement(
By.xpath("//button[@class='v-debugwindow-button' and @title='Clear log']"))
.click();
@@ -99,7 +100,8 @@ public abstract class ReconnectTest extends MultiBrowserTestWithProxy {
message)));
}
- private void waitForDebugMessage(final String expectedMessage) {
+ @Override
+ protected void waitForDebugMessage(final String expectedMessage) {
waitUntil(new ExpectedCondition<Boolean>() {
@Override
diff --git a/uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java b/uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java
index efaf5d493e..fb8a407156 100644
--- a/uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/push/ReconnectWebsocketTest.java
@@ -1,36 +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.push;
-
-import java.util.List;
-
-import org.openqa.selenium.remote.DesiredCapabilities;
-
-import com.vaadin.tests.tb3.WebsocketTest;
-
-public class ReconnectWebsocketTest extends ReconnectTest {
-
- @Override
- public List<DesiredCapabilities> getBrowsersToTest() {
- return WebsocketTest.getWebsocketBrowsers();
- }
-
- @Override
- protected Class<?> getUIClass() {
- return BasicPushWebsocket.class;
- }
-
-}
+///*
+// * 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.List;
+//
+//import org.openqa.selenium.remote.DesiredCapabilities;
+//
+//import com.vaadin.tests.tb3.WebsocketTest;
+//
+//public class ReconnectWebsocketTest extends ReconnectTest {
+//
+// @Override
+// public List<DesiredCapabilities> getBrowsersToTest() {
+// return WebsocketTest.getWebsocketBrowsers();
+// }
+//
+// @Override
+// protected Class<?> getUIClass() {
+// return BasicPushWebsocket.class;
+// }
+//
+// }
diff --git a/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java
index c5c6064555..452a4ad9ee 100644
--- a/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java
+++ b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java
@@ -1,44 +1,44 @@
-/*
- * 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.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.openqa.selenium.remote.DesiredCapabilities;
-
-import com.vaadin.tests.tb3.MultiBrowserTest;
-import com.vaadin.tests.tb3.WebsocketTest;
-
-public class RefreshCloseConnectionTest extends MultiBrowserTest {
- @Test
- public void testSessionRefresh() {
- openTestURL();
-
- Assert.assertEquals("1. Init", getLogRow(0));
-
- openTestURL();
-
- Assert.assertEquals("2. Refresh", getLogRow(1));
- Assert.assertEquals("3. Push", getLogRow(0));
- }
-
- @Override
- public List<DesiredCapabilities> getBrowsersToTest() {
- return WebsocketTest.getWebsocketBrowsers();
- }
-}
+///*
+// * 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.List;
+//
+//import org.junit.Assert;
+//import org.junit.Test;
+//import org.openqa.selenium.remote.DesiredCapabilities;
+//
+//import com.vaadin.tests.tb3.MultiBrowserTest;
+//import com.vaadin.tests.tb3.WebsocketTest;
+//
+//public class RefreshCloseConnectionTest extends MultiBrowserTest {
+// @Test
+// public void testSessionRefresh() {
+// openTestURL();
+//
+// Assert.assertEquals("1. Init", getLogRow(0));
+//
+// openTestURL();
+//
+// Assert.assertEquals("2. Refresh", getLogRow(1));
+// Assert.assertEquals("3. Push", getLogRow(0));
+// }
+//
+// @Override
+// public List<DesiredCapabilities> getBrowsersToTest() {
+// return WebsocketTest.getWebsocketBrowsers();
+// }
+// }
diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
index cfc7b37c98..ad820f3eac 100644
--- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
+++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -16,21 +16,26 @@
package com.vaadin.tests.tb3;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-
-import com.vaadin.testbench.TestBenchElement;
-import org.junit.After;
-import org.junit.Before;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicHttpEntityEnclosingRequest;
+import org.junit.Rule;
import org.junit.runner.RunWith;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
-import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.HasInputDevices;
@@ -38,26 +43,37 @@ 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.remote.BrowserType;
import org.openqa.selenium.remote.DesiredCapabilities;
+import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
+import com.google.gwt.thirdparty.guava.common.base.Joiner;
import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium;
import com.vaadin.server.LegacyApplication;
import com.vaadin.server.UIProvider;
-import com.vaadin.testbench.TestBench;
-import com.vaadin.testbench.TestBenchTestCase;
+import com.vaadin.testbench.TestBenchDriverProxy;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.annotations.BrowserConfiguration;
+import com.vaadin.testbench.elements.CheckBoxElement;
+import com.vaadin.testbench.elements.LabelElement;
+import com.vaadin.testbench.elements.TableElement;
+import com.vaadin.testbench.elements.VerticalLayoutElement;
+import com.vaadin.testbench.parallel.Browser;
+import com.vaadin.testbench.parallel.BrowserUtil;
+import com.vaadin.testbench.parallel.ParallelTest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
-import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
import com.vaadin.ui.UI;
+import elemental.json.JsonObject;
+import elemental.json.impl.JsonUtil;
+
/**
* Base class for TestBench 3+ tests. All TB3+ tests in the project should
* extend this class.
- *
+ *
* Provides:
* <ul>
* <li>Helpers for browser selection</li>
@@ -67,11 +83,15 @@ import com.vaadin.ui.UI;
* and based on requested features, e.g. {@link #isDebug()}, {@link #isPush()}</li>
* <li>Generic helpers for creating TB3+ tests</li>
* </ul>
- *
+ *
* @author Vaadin Ltd
*/
-@RunWith(value = TB3Runner.class)
-public abstract class AbstractTB3Test extends TestBenchTestCase {
+@RunWith(TB3Runner.class)
+public abstract class AbstractTB3Test extends ParallelTest {
+
+ @Rule
+ public RetryOnFail retry = new RetryOnFail();
+
/**
* Height of the screenshots we want to capture
*/
@@ -87,65 +107,29 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
*/
private static final int BROWSER_TIMEOUT_IN_MS = 30 * 1000;
- private DesiredCapabilities desiredCapabilities;
-
private boolean debug = false;
private boolean push = false;
- {
- // Default browser to run on unless setDesiredCapabilities is called
- desiredCapabilities = Browser.FIREFOX.getDesiredCapabilities();
+
+ static {
+ com.vaadin.testbench.Parameters
+ .setScreenshotComparisonCursorDetection(true);
}
/**
* Connect to the hub using a remote web driver, set the canvas size and
* opens the initial URL as specified by {@link #getTestUrl()}
- *
+ *
* @throws Exception
*/
- @Before
+ @Override
public void setup() throws Exception {
- setupDriver();
- }
-
- /**
- * Creates and configure the web driver to be used for the test. By default
- * creates a remote web driver which connects to {@link #getHubURL()} and
- * selects a browser based on {@link #getDesiredCapabilities()}.
- *
- * This method MUST call {@link #setDriver(WebDriver)} with the newly
- * generated driver.
- *
- * @throws Exception
- * If something goes wrong
- */
- protected void setupDriver() throws Exception {
- DesiredCapabilities capabilities;
-
- Browser runLocallyBrowser = getRunLocallyBrowser();
- if (runLocallyBrowser != null) {
- if (System.getenv().containsKey("TEAMCITY_VERSION")) {
- throw new RuntimeException(
- "@RunLocally is not supported for tests run on the build server");
- }
- capabilities = runLocallyBrowser.getDesiredCapabilities();
- setupLocalDriver(capabilities);
- } else {
- capabilities = getDesiredCapabilities();
-
- if (System.getProperty("useLocalWebDriver") != null) {
- setupLocalDriver(capabilities);
- } else {
- WebDriver dr = TestBench.createDriver(new RemoteWebDriver(
- new URL(getHubURL()), capabilities));
- setDriver(dr);
- }
- }
+ super.setup();
int w = SCREENSHOT_WIDTH;
int h = SCREENSHOT_HEIGHT;
- if (BrowserUtil.isIE8(capabilities)) {
+ if (BrowserUtil.isIE8(super.getDesiredCapabilities())) {
// IE8 gets size wrong, who would have guessed...
w += 4;
h += 4;
@@ -158,85 +142,131 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
- protected Browser getRunLocallyBrowser() {
- RunLocally runLocally = getClass().getAnnotation(RunLocally.class);
- if (runLocally != null) {
- return runLocally.value();
- } else {
- return null;
+ /**
+ * Method for closing the tested application.
+ */
+ protected void closeApplication() {
+ if (driver != null) {
+ try {
+ openTestURL("closeApplication");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
}
protected WebElement getTooltipElement() {
- return getDriver().findElement(com.vaadin.testbench.By.className("v-tooltip-text"));
+ return getDriver().findElement(
+ com.vaadin.testbench.By.className("v-tooltip-text"));
}
protected Coordinates getCoordinates(TestBenchElement element) {
return ((Locatable) element.getWrappedElement()).getCoordinates();
}
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.TYPE)
- public @interface RunLocally {
- public Browser value() default Browser.FIREFOX;
+ private boolean hasDebugMessage(String message) {
+ return getDebugMessage(message) != null;
}
- /**
- * Creates a {@link WebDriver} instance used for running the test locally
- * for debug purposes. Used only when {@link #runLocally()} is overridden to
- * return true;
- */
- protected abstract void setupLocalDriver(
- DesiredCapabilities desiredCapabilities);
+ private WebElement getDebugMessage(String message) {
+ return driver.findElement(By.xpath(String.format(
+ "//span[@class='v-debugwindow-message' and text()='%s']",
+ message)));
+ }
+
+ protected void waitForDebugMessage(final String expectedMessage) {
+ waitForDebugMessage(expectedMessage, 30);
+ }
+
+ protected void waitForDebugMessage(final String expectedMessage, int timeout) {
+ waitUntil(new ExpectedCondition<Boolean>() {
+
+ @Override
+ public Boolean apply(WebDriver input) {
+ return hasDebugMessage(expectedMessage);
+ }
+ }, timeout);
+ }
+
+ protected void clearDebugMessages() {
+ driver.findElement(
+ By.xpath("//button[@class='v-debugwindow-button' and @title='Clear log']"))
+ .click();
+ }
+
+ protected void waitUntilRowIsVisible(final TableElement table, final int row) {
+ waitUntil(new ExpectedCondition<Object>() {
+ @Override
+ public Object apply(WebDriver input) {
+ try {
+ return table.getCell(row, 0) != null;
+ } catch (NoSuchElementException e) {
+ return false;
+ }
+ }
+ });
+ }
+
+ protected void scrollTable(TableElement table, int rows, int rowToWait) {
+ testBenchElement(table.findElement(By.className("v-scrollable")))
+ .scroll(rows * 30);
+
+ waitUntilRowIsVisible(table, rowToWait);
+ }
/**
* Opens the given test (defined by {@link #getTestUrl()}, optionally with
* debug window and/or push (depending on {@link #isDebug()} and
* {@link #isPush()}.
*/
- protected void openTestURL() {
- driver.get(getTestUrl());
+ protected void openTestURL(String... parameters) {
+ openTestURL(getUIClass(), parameters);
}
/**
- * Returns the full URL to be used for the test
- *
- * @return the full URL for the test
+ * Opens the given test (defined by {@link #getTestUrl()}, optionally with
+ * debug window and/or push (depending on {@link #isDebug()} and
+ * {@link #isPush()}.
*/
- protected String getTestUrl() {
- String baseUrl = getBaseURL();
- if (baseUrl.endsWith("/")) {
- baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
+ protected void openTestURL(Class<?> uiClass, String... parameters) {
+ String url = getTestURL(uiClass);
+
+ if (parameters.length > 0) {
+ url += "?" + Joiner.on("&").join(parameters);
}
- return baseUrl + getDeploymentPath();
+ driver.get(url);
}
/**
- *
- * @return the location (URL) of the TB hub
+ * Returns the full URL to be used for the test
+ *
+ * @return the full URL for the test
*/
- protected String getHubURL() {
- return "http://" + getHubHostname() + ":4444/wd/hub";
+ protected String getTestUrl() {
+ return StringUtils.strip(getBaseURL(), "/") + getDeploymentPath();
}
/**
- * Used for building the hub URL to use for the test
- *
- * @return the host name of the TestBench hub
+ * Returns the full URL to be used for the test for the provided UI class.
+ *
+ * @return the full URL for the test
*/
- protected abstract String getHubHostname();
+ protected String getTestURL(Class<?> uiClass) {
+ return StringUtils.strip(getBaseURL(), "/")
+ + getDeploymentPath(uiClass);
+ }
/**
* Used to determine what URL to initially open for the test
- *
+ *
* @return the host name of development server
*/
protected abstract String getDeploymentHostname();
/**
* Used to determine what port the test is running on
- *
+ *
* @return The port teh test is running on, by default 8888
*/
protected abstract int getDeploymentPort();
@@ -248,57 +278,23 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* ran and before running that,
* {@link #setDesiredCapabilities(DesiredCapabilities)} is invoked with the
* value returned by this method.
- *
+ *
* This method is not static to allow overriding it in sub classes. By
* default runs the test only on Firefox
- *
+ *
* @return The browsers to run the test on
*/
+ @BrowserConfiguration
public List<DesiredCapabilities> getBrowsersToTest() {
return Collections.singletonList(Browser.FIREFOX
.getDesiredCapabilities());
}
/**
- * Used to determine which capabilities should be used when setting up a
- * {@link WebDriver} for this test. Typically set by a test runner or left
- * at its default (Firefox 24). If you want to run a test on a single
- * browser other than Firefox 24 you can override this method.
- *
- * @return the requested browser capabilities
- */
- protected DesiredCapabilities getDesiredCapabilities() {
- return desiredCapabilities;
- }
-
- /**
- * Sets the requested browser capabilities (typically browser name and
- * version)
- *
- * @param desiredCapabilities
- */
- public void setDesiredCapabilities(DesiredCapabilities desiredCapabilities) {
- this.desiredCapabilities = desiredCapabilities;
- }
-
- /**
- * Shuts down the driver after the test has been completed
- *
- * @throws Exception
- */
- @After
- public void tearDown() throws Exception {
- if (driver != null) {
- driver.quit();
- }
- driver = null;
- }
-
- /**
* Finds an element based on the part of a TB2 style locator following the
* :: (e.g. vaadin=runLabelModes::PID_Scheckboxaction-Enabled/domChild[0] ->
* PID_Scheckboxaction-Enabled/domChild[0]).
- *
+ *
* @param vaadinLocator
* The part following :: of the vaadin locator string
* @return
@@ -309,12 +305,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Uses JavaScript to determine the currently focused element.
- *
+ *
* @return Focused element or null
*/
protected WebElement getFocusedElement() {
- Object focusedElement = ((JavascriptExecutor) getDriver())
- .executeScript("return document.activeElement");
+ Object focusedElement = executeScript("return document.activeElement");
if (null != focusedElement) {
return (WebElement) focusedElement;
} else {
@@ -323,8 +318,21 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
/**
+ * Executes the given Javascript
+ *
+ * @param script
+ * the script to execute
+ * @return whatever
+ * {@link org.openqa.selenium.JavascriptExecutor#executeScript(String, Object...)}
+ * returns
+ */
+ protected Object executeScript(String script) {
+ return ((JavascriptExecutor) getDriver()).executeScript(script);
+ }
+
+ /**
* Find a Vaadin element based on its id given using Component.setId
- *
+ *
* @param id
* The id to locate
* @return
@@ -338,7 +346,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* following the :: (e.g.
* vaadin=runLabelModes::PID_Scheckboxaction-Enabled/domChild[0] ->
* PID_Scheckboxaction-Enabled/domChild[0]).
- *
+ *
* @param vaadinLocator
* The part following :: of the vaadin locator string
* @return
@@ -352,7 +360,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Constructs a {@link By} locator for the id given using Component.setId
- *
+ *
* @param id
* The id to locate
* @return a locator for the given id
@@ -364,11 +372,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Waits up to 10s for the given condition to become true. Use e.g. as
* {@link #waitUntil(ExpectedConditions.textToBePresentInElement(by, text))}
- *
+ *
* @param condition
* the condition to wait for to become true
*/
- protected void waitUntil(ExpectedCondition<Boolean> condition) {
+ protected <T> void waitUntil(ExpectedCondition<T> condition) {
waitUntil(condition, 10);
}
@@ -376,11 +384,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Waits the given number of seconds for the given condition to become true.
* Use e.g. as {@link
* #waitUntil(ExpectedConditions.textToBePresentInElement(by, text))}
- *
+ *
* @param condition
* the condition to wait for to become true
*/
- protected void waitUntil(ExpectedCondition<Boolean> condition,
+ protected <T> void waitUntil(ExpectedCondition<T> condition,
long timeoutInSeconds) {
new WebDriverWait(driver, timeoutInSeconds).until(condition);
}
@@ -389,11 +397,11 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Waits up to 10s for the given condition to become false. Use e.g. as
* {@link #waitUntilNot(ExpectedConditions.textToBePresentInElement(by,
* text))}
- *
+ *
* @param condition
* the condition to wait for to become false
*/
- protected void waitUntilNot(ExpectedCondition<Boolean> condition) {
+ protected <T> void waitUntilNot(ExpectedCondition<T> condition) {
waitUntilNot(condition, 10);
}
@@ -401,24 +409,52 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Waits the given number of seconds for the given condition to become
* false. Use e.g. as {@link
* #waitUntilNot(ExpectedConditions.textToBePresentInElement(by, text))}
- *
+ *
* @param condition
* the condition to wait for to become false
*/
- protected void waitUntilNot(ExpectedCondition<Boolean> condition,
+ protected <T> void waitUntilNot(ExpectedCondition<T> condition,
long timeoutInSeconds) {
waitUntil(ExpectedConditions.not(condition), timeoutInSeconds);
}
- protected void waitForElementToBePresent(By by) {
- waitUntil(ExpectedConditions.not(ExpectedConditions
- .invisibilityOfElementLocated(by)));
+ protected void waitForElementPresent(final By by) {
+ waitUntil(ExpectedConditions.presenceOfElementLocated(by));
+ }
+
+ protected void waitForElementVisible(final By by) {
+ waitUntil(ExpectedConditions.visibilityOfElementLocated(by));
+ }
+
+ /**
+ * Checks if the given element has the given class name.
+ *
+ * Matches only full class names, i.e. has ("foo") does not match
+ * class="foobar"
+ *
+ * @param element
+ * @param className
+ * @return
+ */
+ protected boolean hasCssClass(WebElement element, String className) {
+ String classes = element.getAttribute("class");
+ if (classes == null || classes.isEmpty()) {
+ return (className == null || className.isEmpty());
+ }
+
+ for (String cls : classes.split(" ")) {
+ if (className.equals(cls)) {
+ return true;
+ }
+ }
+
+ return false;
}
/**
* For tests extending {@link AbstractTestUIWithLog}, returns the element
* for the Nth log row
- *
+ *
* @param rowNr
* The log row to retrieve
* @return the Nth log row
@@ -430,7 +466,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* For tests extending {@link AbstractTestUIWithLog}, returns the text in
* the Nth log row
- *
+ *
* @param rowNr
* The log row to retrieve text for
* @return the text in the log row
@@ -441,7 +477,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Asserts that {@literal a} is &gt;= {@literal b}
- *
+ *
* @param message
* The message to include in the {@link AssertionError}
* @param a
@@ -460,7 +496,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Asserts that {@literal a} is &gt; {@literal b}
- *
+ *
* @param message
* The message to include in the {@link AssertionError}
* @param a
@@ -478,7 +514,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Asserts that {@literal a} is &lt;= {@literal b}
- *
+ *
* @param message
* The message to include in the {@link AssertionError}
* @param a
@@ -497,7 +533,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Asserts that {@literal a} is &lt; {@literal b}
- *
+ *
* @param message
* The message to include in the {@link AssertionError}
* @param a
@@ -522,12 +558,12 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Returns the path that should be used for the test. The path contains the
* full path (appended to hostname+port) and must start with a slash.
- *
+ *
* @param push
* true if "?debug" should be added
* @param debug
* true if /run-push should be used instead of /run
- *
+ *
* @return The URL path to the UI class to test
*/
protected String getDeploymentPath() {
@@ -544,13 +580,13 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Returns the UI class the current test is connected to (or in special
* cases UIProvider or LegacyApplication). Uses the enclosing class if the
* test class is a static inner class to a UI class.
- *
+ *
* Test which are not enclosed by a UI class must implement this method and
* return the UI class they want to test.
- *
+ *
* Note that this method will update the test name to the enclosing class to
* be compatible with TB2 screenshot naming
- *
+ *
* @return the UI class the current test is connected to
*/
protected Class<?> getUIClass() {
@@ -588,7 +624,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Returns whether to run the test in debug mode (with the debug console
* open) or not
- *
+ *
* @return true to run with the debug window open, false by default
*/
protected final boolean isDebug() {
@@ -598,7 +634,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Sets whether to run the test in debug mode (with the debug console open)
* or not.
- *
+ *
* @param debug
* true to open debug window, false otherwise
*/
@@ -610,7 +646,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Returns whether to run the test with push enabled (using /run-push) or
* not. Note that push tests can and should typically be created using @Push
* on the UI instead of overriding this method
- *
+ *
* @return true if /run-push is used, false otherwise
*/
protected final boolean isPush() {
@@ -621,7 +657,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Sets whether to run the test with push enabled (using /run-push) or not.
* Note that push tests can and should typically be created using @Push on
* the UI instead of overriding this method
- *
+ *
* @param push
* true to use /run-push in the test, false otherwise
*/
@@ -633,10 +669,10 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* Returns the path for the given UI class when deployed on the test server.
* The path contains the full path (appended to hostname+port) and must
* start with a slash.
- *
+ *
* This method takes into account {@link #isPush()} and {@link #isDebug()}
* when the path is generated.
- *
+ *
* @param uiClass
* @param push
* true if "?debug" should be added
@@ -644,13 +680,14 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
* true if /run-push should be used instead of /run
* @return The path to the given UI class
*/
- private String getDeploymentPath(Class<?> uiClass) {
+ protected String getDeploymentPath(Class<?> uiClass) {
String runPath = "/run";
if (isPush()) {
runPath = "/run-push";
}
- if (UI.class.isAssignableFrom(uiClass)) {
+ if (UI.class.isAssignableFrom(uiClass)
+ || UIProvider.class.isAssignableFrom(uiClass)) {
return runPath + "/" + uiClass.getCanonicalName()
+ (isDebug() ? "?debug" : "");
} else if (LegacyApplication.class.isAssignableFrom(uiClass)) {
@@ -665,7 +702,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Used to determine what URL to initially open for the test
- *
+ *
* @return The base URL for the test. Does not include a trailing slash.
*/
protected String getBaseURL() {
@@ -675,7 +712,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Generates the application id based on the URL in a way compatible with
* VaadinServletService.
- *
+ *
* @param pathWithQueryParameters
* The path part of the URL, possibly still containing query
* parameters
@@ -696,7 +733,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Sleeps for the given number of ms but ensures that the browser connection
* does not time out.
- *
+ *
* @param timeoutMillis
* Number of ms to wait
* @throws InterruptedException
@@ -713,250 +750,9 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
/**
- * Provides helper method for selecting the browser to run on
- *
- * @author Vaadin Ltd
- */
- public static class BrowserUtil {
- /**
- * Gets the capabilities for Safari of the given version
- *
- * @param version
- * the major version
- * @return an object describing the capabilities required for running a
- * test on the given Safari version
- */
- public static DesiredCapabilities safari(int version) {
- DesiredCapabilities c = DesiredCapabilities.safari();
- c.setPlatform(Platform.MAC);
- c.setVersion("" + version);
- return c;
- }
-
- /**
- * Gets the capabilities for Chrome of the given version
- *
- * @param version
- * the major version
- * @return an object describing the capabilities required for running a
- * test on the given Chrome version
- */
- public static DesiredCapabilities chrome(int version) {
- DesiredCapabilities c = DesiredCapabilities.chrome();
- c.setVersion("" + version);
- c.setPlatform(Platform.XP);
- return c;
- }
-
- /**
- * Gets the capabilities for Opera of the given version
- *
- * @param version
- * the major version
- * @return an object describing the capabilities required for running a
- * test on the given Opera version
- */
- public static DesiredCapabilities opera(int version) {
- DesiredCapabilities c = DesiredCapabilities.opera();
- c.setVersion("" + version);
- c.setPlatform(Platform.XP);
- return c;
- }
-
- /**
- * Gets the capabilities for Firefox of the given version
- *
- * @param version
- * the major version
- * @return an object describing the capabilities required for running a
- * test on the given Firefox version
- */
- public static DesiredCapabilities firefox(int version) {
- DesiredCapabilities c = DesiredCapabilities.firefox();
- c.setVersion("" + version);
- c.setPlatform(Platform.XP);
- return c;
- }
-
- /**
- * Gets the capabilities for Internet Explorer of the given version
- *
- * @param version
- * the major version
- * @return an object describing the capabilities required for running a
- * test on the given Internet Explorer version
- */
- public static DesiredCapabilities ie(int version) {
- DesiredCapabilities c = DesiredCapabilities.internetExplorer();
- c.setVersion("" + version);
- return c;
- }
-
- /**
- * Gets the capabilities for PhantomJS of the given version
- *
- * @param version
- * the major version
- * @return an object describing the capabilities required for running a
- * test on the given PhantomJS version
- */
- public static DesiredCapabilities phantomJS(int version) {
- DesiredCapabilities c = DesiredCapabilities.phantomjs();
- c.setPlatform(Platform.LINUX);
- c.setVersion("" + version);
- return c;
- }
-
- /**
- * Checks if the given capabilities refer to Internet Explorer 8
- *
- * @param capabilities
- * @return true if the capabilities refer to IE8, false otherwise
- */
- public static boolean isIE8(DesiredCapabilities capabilities) {
- return isIE(capabilities) && "8".equals(capabilities.getVersion());
- }
-
- /**
- * @param capabilities
- * The capabilities to check
- * @return true if the capabilities refer to Internet Explorer, false
- * otherwise
- */
- public static boolean isIE(DesiredCapabilities capabilities) {
- return BrowserType.IE.equals(capabilities.getBrowserName());
- }
-
- /**
- * @param capabilities
- * The capabilities to check
- * @return true if the capabilities refer to Chrome, false otherwise
- */
- public static boolean isChrome(DesiredCapabilities capabilities) {
- return BrowserType.CHROME.equals(capabilities.getBrowserName());
- }
-
- /**
- * @param capabilities
- * The capabilities to check
- * @return true if the capabilities refer to Opera, false otherwise
- */
- public static boolean isOpera(DesiredCapabilities capabilities) {
- return BrowserType.OPERA.equals(capabilities.getBrowserName());
- }
-
- /**
- * @param capabilities
- * The capabilities to check
- * @return true if the capabilities refer to Safari, false otherwise
- */
- public static boolean isSafari(DesiredCapabilities capabilities) {
- return BrowserType.SAFARI.equals(capabilities.getBrowserName());
- }
-
- /**
- * @param capabilities
- * The capabilities to check
- * @return true if the capabilities refer to Firefox, false otherwise
- */
- public static boolean isFirefox(DesiredCapabilities capabilities) {
- return BrowserType.FIREFOX.equals(capabilities.getBrowserName());
- }
-
- /**
- * @param capabilities
- * The capabilities to check
- * @return true if the capabilities refer to PhantomJS, false otherwise
- */
- public static boolean isPhantomJS(DesiredCapabilities capabilities) {
- return BrowserType.PHANTOMJS.equals(capabilities.getBrowserName());
- }
-
- /**
- * Returns a human readable identifier of the given browser. Used for
- * test naming and screenshots
- *
- * @param capabilities
- * @return a human readable string describing the capabilities
- */
- public static String getBrowserIdentifier(
- DesiredCapabilities capabilities) {
- if (isIE(capabilities)) {
- return "InternetExplorer";
- } else if (isFirefox(capabilities)) {
- return "Firefox";
- } else if (isChrome(capabilities)) {
- return "Chrome";
- } else if (isSafari(capabilities)) {
- return "Safari";
- } else if (isOpera(capabilities)) {
- return "Opera";
- } else if (isPhantomJS(capabilities)) {
- return "PhantomJS";
- }
-
- return capabilities.getBrowserName();
- }
-
- /**
- * Returns a human readable identifier of the platform described by the
- * given capabilities. Used mainly for screenshots
- *
- * @param capabilities
- * @return a human readable string describing the platform
- */
- public static String getPlatform(DesiredCapabilities capabilities) {
- if (capabilities.getPlatform() == Platform.WIN8
- || capabilities.getPlatform() == Platform.WINDOWS
- || capabilities.getPlatform() == Platform.VISTA
- || capabilities.getPlatform() == Platform.XP) {
- return "Windows";
- } else if (capabilities.getPlatform() == Platform.MAC) {
- return "Mac";
- }
- return capabilities.getPlatform().toString();
- }
-
- /**
- * Returns a string which uniquely (enough) identifies this browser.
- * Used mainly in screenshot names.
- *
- * @param capabilities
- *
- * @return a unique string for each browser
- */
- public static String getUniqueIdentifier(
- DesiredCapabilities capabilities) {
- return getUniqueIdentifier(getPlatform(capabilities),
- getBrowserIdentifier(capabilities),
- capabilities.getVersion());
- }
-
- /**
- * Returns a string which uniquely (enough) identifies this browser.
- * Used mainly in screenshot names.
- *
- * @param capabilities
- *
- * @return a unique string for each browser
- */
- public static String getUniqueIdentifier(
- DesiredCapabilities capabilities, String versionOverride) {
- return getUniqueIdentifier(getPlatform(capabilities),
- getBrowserIdentifier(capabilities), versionOverride);
- }
-
- private static String getUniqueIdentifier(String platform,
- String browser, String version) {
- return platform + "_" + browser + "_" + version;
- }
-
- }
-
- /**
* Called by the test runner whenever there is an exception in the test that
* will cause termination of the test
- *
+ *
* @param t
* the throwable which caused the termination
*/
@@ -967,7 +763,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Returns the mouse object for doing mouse commands
- *
+ *
* @return Returns the mouse
*/
public Mouse getMouse() {
@@ -976,7 +772,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
/**
* Returns the keyboard object for controlling keyboard events
- *
+ *
* @return Return the keyboard
*/
public Keyboard getKeyboard() {
@@ -995,7 +791,134 @@ public abstract class AbstractTB3Test extends TestBenchTestCase {
}
protected void openDebugLogTab() {
- findElement(By.xpath("//button[@title='Debug message log']")).click();
+
+ waitUntil(new ExpectedCondition<Boolean>() {
+ @Override
+ public Boolean apply(WebDriver input) {
+ WebElement element = getDebugLogButton();
+ return element != null;
+ }
+ }, 15);
+ getDebugLogButton().click();
}
+ private WebElement getDebugLogButton() {
+ return findElement(By.xpath("//button[@title='Debug message log']"));
+ }
+
+ /**
+ * Should the "require window focus" be enabled for Internet Explorer.
+ * RequireWindowFocus makes tests more stable but seems to be broken with
+ * certain commands such as sendKeys. Therefore it is not enabled by default
+ * for all tests
+ *
+ * @return true, to use the "require window focus" feature, false otherwise
+ */
+ protected boolean requireWindowFocusForIE() {
+ return false;
+ }
+
+ /**
+ * Should the "enable persistent hover" be enabled for Internet Explorer.
+ *
+ * Persistent hovering causes continuous firing of mouse over events at the
+ * last location the mouse cursor has been moved to. This is to avoid
+ * problems where the real mouse cursor is inside the browser window and
+ * Internet Explorer uses that location for some undefined operation
+ * (http://
+ * jimevansmusic.blogspot.fi/2012/06/whats-wrong-with-internet-explorer
+ * .html)
+ *
+ * @return true, to use the "persistent hover" feature, false otherwise
+ */
+ protected boolean usePersistentHoverForIE() {
+ return true;
+ }
+
+ // FIXME: Remove this once TB4 getRemoteControlName works properly
+ private RemoteWebDriver getRemoteDriver() {
+ WebDriver d = getDriver();
+ if (d instanceof TestBenchDriverProxy) {
+ try {
+ Field f = TestBenchDriverProxy.class
+ .getDeclaredField("actualDriver");
+ f.setAccessible(true);
+ return (RemoteWebDriver) f.get(d);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (d instanceof RemoteWebDriver) {
+ return (RemoteWebDriver) d;
+ }
+
+ return null;
+
+ }
+
+ // FIXME: Remove this once TB4 getRemoteControlName works properly
+ protected String getRemoteControlName() {
+ try {
+ RemoteWebDriver d = getRemoteDriver();
+ if (d == null) {
+ return null;
+ }
+ HttpCommandExecutor ce = (HttpCommandExecutor) d
+ .getCommandExecutor();
+ String hostName = ce.getAddressOfRemoteServer().getHost();
+ int port = ce.getAddressOfRemoteServer().getPort();
+ HttpHost host = new HttpHost(hostName, port);
+ DefaultHttpClient client = new DefaultHttpClient();
+ URL sessionURL = new URL("http://" + hostName + ":" + port
+ + "/grid/api/testsession?session=" + d.getSessionId());
+ BasicHttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest(
+ "POST", sessionURL.toExternalForm());
+ HttpResponse response = client.execute(host, r);
+ JsonObject object = extractObject(response);
+ URL myURL = new URL(object.getString("proxyId"));
+ if ((myURL.getHost() != null) && (myURL.getPort() != -1)) {
+ return myURL.getHost();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ protected boolean logContainsText(String string) {
+ List<String> logs = getLogs();
+
+ for (String text : logs) {
+ if (text.contains(string)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ protected List<String> getLogs() {
+ VerticalLayoutElement log = $(VerticalLayoutElement.class).id("Log");
+ List<LabelElement> logLabels = log.$(LabelElement.class).all();
+ List<String> logTexts = new ArrayList<String>();
+
+ for (LabelElement label : logLabels) {
+ logTexts.add(label.getText());
+ }
+
+ return logTexts;
+ }
+
+ private static JsonObject extractObject(HttpResponse resp)
+ throws IOException {
+ InputStream contents = resp.getEntity().getContent();
+ StringWriter writer = new StringWriter();
+ IOUtils.copy(contents, writer, "UTF8");
+ return JsonUtil.parse(writer.toString());
+ }
+
+ protected void click(CheckBoxElement checkbox) {
+ checkbox.findElement(By.xpath("input")).click();
+ }
}
diff --git a/uitest/src/com/vaadin/tests/tb3/AffectedTB3TestLocator.java b/uitest/src/com/vaadin/tests/tb3/AffectedTB3TestLocator.java
new file mode 100644
index 0000000000..d65eba278b
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/AffectedTB3TestLocator.java
@@ -0,0 +1,92 @@
+/*
+ * 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.tb3;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class AffectedTB3TestLocator extends TB3TestLocator {
+
+ private final ChangedTB3TestLocator changedTB3TestLocator;
+
+ public AffectedTB3TestLocator() {
+ changedTB3TestLocator = new ChangedTB3TestLocator();
+ }
+
+ @Override
+ protected <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+ String basePackage, String[] ignoredPackages) throws IOException {
+ List<Class<? extends T>> allTestClasses = super.findClasses(baseClass,
+ basePackage, ignoredPackages);
+
+ List<Class<? extends T>> changedTestClasses = changedTB3TestLocator
+ .findClasses(baseClass, basePackage, ignoredPackages);
+
+ return getAffectedTestClasses(allTestClasses, changedTestClasses);
+ }
+
+ private <T> List<Class<? extends T>> getAffectedTestClasses(
+ List<Class<? extends T>> allTestClasses,
+ List<Class<? extends T>> changedTestClasses) throws IOException {
+
+ Set testClasses = new HashSet(changedTestClasses);
+ testClasses
+ .addAll(getTestClassesWithAffectedPackageName(allTestClasses));
+
+ List<Class<? extends T>> affectedTestClasses = new ArrayList<Class<? extends T>>();
+ affectedTestClasses.addAll(testClasses);
+
+ return affectedTestClasses;
+ }
+
+ private <T> List<Class<? extends T>> getTestClassesWithAffectedPackageName(
+ List<Class<? extends T>> classes) {
+ List<Class<? extends T>> affectedTestClasses = new ArrayList<Class<? extends T>>();
+ List<String> affectedFiles = getAffectedFiles();
+
+ for (Class c : classes) {
+ String[] packageParts = c.getName().split("\\.");
+ String lastPart = packageParts[packageParts.length - 2];
+
+ for (String f : affectedFiles) {
+ if (f.toLowerCase().contains(lastPart.toLowerCase())) {
+ affectedTestClasses.add(c);
+
+ // Break here not to accidentally add the same test class
+ // multiple times if it matches more than one file.
+ break;
+ }
+ }
+ }
+
+ return affectedTestClasses;
+ }
+
+ private List<String> getAffectedFiles() {
+ List<String> affectedFilePaths = new ArrayList<String>();
+
+ for (String path : changedTB3TestLocator.getChangedFilePaths()) {
+ if (!path.toLowerCase().contains("test")) {
+ affectedFilePaths.add(path);
+ }
+ }
+
+ return affectedFilePaths;
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java
new file mode 100644
index 0000000000..d9f90bc7ca
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java
@@ -0,0 +1,28 @@
+package com.vaadin.tests.tb3;
+
+import java.io.IOException;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+
+import com.vaadin.tests.tb3.AffectedTB3Tests.AffectedTB3TestSuite;
+
+/**
+ * Test suite that runs tests from test classes which have changes or have
+ * similar package name compare the the changes files in the current workspace.
+ * If there are no changes in the workspace, it will run the changes to test
+ * classes introduced in the HEAD commit.
+ *
+ * @author Vaadin Ltd
+ */
+@RunWith(AffectedTB3TestSuite.class)
+public class AffectedTB3Tests {
+ public static class AffectedTB3TestSuite extends TB3TestSuite {
+ public AffectedTB3TestSuite(Class<?> klass) throws InitializationError,
+ IOException {
+ super(klass, AbstractTB3Test.class, "com.vaadin.tests",
+ new String[] { "com.vaadin.tests.integration" },
+ new AffectedTB3TestLocator());
+ }
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java
index b7cc8284d1..def4460070 100644
--- a/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java
+++ b/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -16,6 +16,8 @@
package com.vaadin.tests.tb3;
+import java.io.IOException;
+
import org.junit.runner.RunWith;
import org.junit.runners.model.InitializationError;
@@ -24,7 +26,7 @@ import com.vaadin.tests.tb3.AllTB3Tests.AllTB3TestsSuite;
/**
* Test consisting of all TB3 tests except integration tests (classes extending
* AbstractTB3Test, excludes package com.vaadin.test.integration).
- *
+ *
* @author Vaadin Ltd
*/
@RunWith(AllTB3TestsSuite.class)
@@ -32,7 +34,8 @@ public class AllTB3Tests {
public static class AllTB3TestsSuite extends TB3TestSuite {
- public AllTB3TestsSuite(Class<?> klass) throws InitializationError {
+ public AllTB3TestsSuite(Class<?> klass) throws InitializationError,
+ IOException {
super(klass, AbstractTB3Test.class, "com.vaadin.tests",
new String[] { "com.vaadin.tests.integration" });
}
diff --git a/uitest/src/com/vaadin/tests/tb3/ChangedTB3TestLocator.java b/uitest/src/com/vaadin/tests/tb3/ChangedTB3TestLocator.java
new file mode 100644
index 0000000000..0ae9472134
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/ChangedTB3TestLocator.java
@@ -0,0 +1,170 @@
+/*
+ * 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.tb3;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.api.DiffCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawTextComparator;
+import org.eclipse.jgit.errors.AmbiguousObjectException;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.eclipse.jgit.util.io.DisabledOutputStream;
+
+/**
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class ChangedTB3TestLocator extends TB3TestLocator {
+
+ @Override
+ protected <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+ String basePackage, String[] ignoredPackages) throws IOException {
+
+ return getChangedTestClasses(baseClass);
+ }
+
+ protected List<String> getChangedFilePaths() {
+ List<String> filePaths = new ArrayList<String>();
+
+ for (DiffEntry diff : getDiffs()) {
+ if (diff.getChangeType() != ChangeType.DELETE) {
+ filePaths.add(diff.getNewPath());
+ System.out.println("Using changed file: " + diff.getNewPath());
+ }
+ }
+
+ return filePaths;
+ }
+
+ private List<DiffEntry> getDiffs() {
+ try {
+ FileRepositoryBuilder builder = new FileRepositoryBuilder();
+ Repository repository = builder.setWorkTree(new File("."))
+ .readEnvironment() // scan environment GIT_* variables
+ .findGitDir() // scan up the file system tree
+ .build();
+
+ List<DiffEntry> diffsInWorkingTree = getDiffsInWorkingTree(repository);
+
+ if (diffsInWorkingTree.isEmpty()) {
+ return getDiffsInHead(repository);
+ }
+
+ return diffsInWorkingTree;
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (NoWorkTreeException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (GitAPIException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ private List<DiffEntry> getDiffsInWorkingTree(Repository repository)
+ throws GitAPIException {
+ Git git = new Git(repository);
+ DiffCommand diffCommand = git.diff();
+
+ List<DiffEntry> diffsInWorkingTree = new ArrayList<DiffEntry>();
+
+ for (DiffEntry diff : diffCommand.call()) {
+ if (pathIsExcluded(diff.getNewPath())) {
+ continue;
+ }
+
+ diffsInWorkingTree.add(diff);
+ }
+
+ return diffsInWorkingTree;
+ }
+
+ private boolean pathIsExcluded(String path) {
+ // Exclude temporary junit files and screenshots.
+ return path.startsWith("uitest/junit")
+ || getScreenshotDirectory().contains(path);
+ }
+
+ private String getScreenshotDirectory() {
+ return PrivateTB3Configuration
+ .getProperty(PrivateTB3Configuration.SCREENSHOT_DIRECTORY);
+ }
+
+ private List<DiffEntry> getDiffsInHead(Repository repository)
+ throws AmbiguousObjectException, IncorrectObjectTypeException,
+ IOException, MissingObjectException {
+ RevWalk rw = new RevWalk(repository);
+ ObjectId head = repository.resolve(Constants.HEAD);
+ RevCommit commit = rw.parseCommit(head);
+ RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
+ DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
+ df.setRepository(repository);
+ df.setDiffComparator(RawTextComparator.DEFAULT);
+ df.setDetectRenames(true);
+ List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());
+
+ return diffs;
+ }
+
+ private <T> List<Class<? extends T>> getChangedTestClasses(
+ Class<T> baseClass) {
+ List<String> changedTestFilePaths = getTestFilePaths();
+ List<Class<? extends T>> testClasses = new ArrayList<Class<? extends T>>();
+
+ for (String filePath : changedTestFilePaths) {
+ String path = filePath.replace("uitest/src/", "").replace(".java",
+ "");
+ String className = path.replace("/", ".");
+ addClassIfMatches(testClasses, className, baseClass);
+ }
+
+ return testClasses;
+ }
+
+ private List<String> getTestFilePaths() {
+ List<String> changedTestFilePaths = new ArrayList<String>();
+
+ for (String filePath : getChangedFilePaths()) {
+ if (filePath.toLowerCase().startsWith("uitest")
+ && filePath.toLowerCase().endsWith(".java")) {
+ changedTestFilePaths.add(filePath);
+ }
+ }
+
+ return changedTestFilePaths;
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java
new file mode 100644
index 0000000000..2ca4ed20d7
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java
@@ -0,0 +1,44 @@
+/*
+ * 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.tb3;
+
+import java.io.IOException;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+
+import com.vaadin.tests.tb3.ChangedTB3Tests.ChangedTB3TestsSuite;
+
+/**
+ * Test suite that runs tests from test classes which have changes in the
+ * current workspace. If there are no changes in the workspace, it will run the
+ * changes to test classes introduced in the HEAD commit.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+@RunWith(ChangedTB3TestsSuite.class)
+public class ChangedTB3Tests {
+ public static class ChangedTB3TestsSuite extends TB3TestSuite {
+ public ChangedTB3TestsSuite(Class<?> klass) throws InitializationError,
+ IOException {
+ super(klass, AbstractTB3Test.class, "com.vaadin.tests",
+ new String[] { "com.vaadin.tests.integration" },
+ new ChangedTB3TestLocator());
+
+ }
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java
index ccbb6ca872..217a3b56a4 100644
--- a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java
+++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -17,82 +17,94 @@
package com.vaadin.tests.tb3;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
+import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
+import com.vaadin.testbench.parallel.Browser;
+import com.vaadin.testbench.parallel.BrowserUtil;
+
/**
* Base class for tests which should be run on all supported browsers. The test
* is automatically launched for multiple browsers in parallel by the test
* runner.
- *
+ *
* Sub classes can, but typically should not, restrict the browsers used by
* implementing a
- *
+ *
* <pre>
* &#064;Parameters
* public static Collection&lt;DesiredCapabilities&gt; getBrowsersForTest() {
* }
* </pre>
- *
+ *
* @author Vaadin Ltd
*/
public abstract class MultiBrowserTest extends PrivateTB3Configuration {
- protected List<DesiredCapabilities> getBrowsersExcludingIE() {
- List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>(getAllBrowsers());
- browsers.remove(Browser.IE8.getDesiredCapabilities());
- browsers.remove(Browser.IE9.getDesiredCapabilities());
- browsers.remove(Browser.IE10.getDesiredCapabilities());
- browsers.remove(Browser.IE11.getDesiredCapabilities());
+ protected List<DesiredCapabilities> getBrowsersSupportingWebSocket() {
+ // No WebSocket support in IE8-9 and PhantomJS
+ return getBrowserCapabilities(Browser.IE10, Browser.IE11,
+ Browser.FIREFOX, Browser.CHROME);
+ }
- return browsers;
+ protected List<DesiredCapabilities> getBrowsersExcludingPhantomJS() {
+ return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10,
+ Browser.IE11, Browser.CHROME, Browser.FIREFOX);
}
- public enum Browser {
- FIREFOX(BrowserUtil.firefox(24)), CHROME(BrowserUtil.chrome(33)), SAFARI(
- BrowserUtil.safari(7)), IE8(BrowserUtil.ie(8)), IE9(BrowserUtil
- .ie(9)), IE10(BrowserUtil.ie(10)), IE11(BrowserUtil.ie(11)), OPERA(
- BrowserUtil.opera(17)), PHANTOMJS(BrowserUtil.phantomJS(1));
- private DesiredCapabilities desiredCapabilities;
+ protected List<DesiredCapabilities> getBrowsersExcludingIE() {
+ return getBrowserCapabilities(Browser.FIREFOX, Browser.CHROME,
+ Browser.PHANTOMJS);
+ }
- private Browser(DesiredCapabilities desiredCapabilities) {
- this.desiredCapabilities = desiredCapabilities;
- }
+ protected List<DesiredCapabilities> getBrowsersExcludingIE8() {
+ return getBrowserCapabilities(Browser.IE9, Browser.IE10, Browser.IE11,
+ Browser.FIREFOX, Browser.CHROME, Browser.PHANTOMJS);
+ }
- public DesiredCapabilities getDesiredCapabilities() {
- return desiredCapabilities;
- }
+ protected List<DesiredCapabilities> getBrowsersSupportingShiftClick() {
+ return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10,
+ Browser.IE11, Browser.CHROME);
}
- static List<DesiredCapabilities> allBrowsers = new ArrayList<DesiredCapabilities>();
- static {
- allBrowsers.add(Browser.IE8.getDesiredCapabilities());
- allBrowsers.add(Browser.IE9.getDesiredCapabilities());
- allBrowsers.add(Browser.IE10.getDesiredCapabilities());
- allBrowsers.add(Browser.IE11.getDesiredCapabilities());
- allBrowsers.add(Browser.FIREFOX.getDesiredCapabilities());
- // Uncomment once we have the capability to run on Safari 6
- // allBrowsers.add(SAFARI);
- allBrowsers.add(Browser.CHROME.getDesiredCapabilities());
- allBrowsers.add(Browser.PHANTOMJS.getDesiredCapabilities());
- // Re-enable this when it is possible to run on a modern Opera version
- // allBrowsers.add(Browser.OPERA.getDesiredCapabilities());
+ protected List<DesiredCapabilities> getIEBrowsersOnly() {
+ return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10,
+ Browser.IE11);
}
- /**
- * @return all supported browsers which are actively tested
- */
- public static List<DesiredCapabilities> getAllBrowsers() {
- return Collections.unmodifiableList(allBrowsers);
+ @Override
+ public void setDesiredCapabilities(DesiredCapabilities desiredCapabilities) {
+ if (BrowserUtil.isIE(desiredCapabilities)) {
+ if (requireWindowFocusForIE()) {
+ desiredCapabilities.setCapability(
+ InternetExplorerDriver.REQUIRE_WINDOW_FOCUS, true);
+ }
+ if (!usePersistentHoverForIE()) {
+ desiredCapabilities.setCapability(
+ InternetExplorerDriver.ENABLE_PERSISTENT_HOVERING,
+ false);
+ }
+ }
+
+ super.setDesiredCapabilities(desiredCapabilities);
}
@Override
public List<DesiredCapabilities> getBrowsersToTest() {
- // Return a copy so sub classes can do
- // super.getBrowseresToTest().remove(something)
- return new ArrayList<DesiredCapabilities>(getAllBrowsers());
+ // Uncomment Safari and Opera if those become tested browsers again.
+ return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10,
+ Browser.IE11, Browser.FIREFOX, Browser.CHROME,
+ Browser.PHANTOMJS /* , Browser.SAFARI, Browser.OPERA */);
}
+ protected List<DesiredCapabilities> getBrowserCapabilities(
+ Browser... browsers) {
+ List<DesiredCapabilities> capabilities = new ArrayList<DesiredCapabilities>();
+ for (Browser browser : browsers) {
+ capabilities.add(browser.getDesiredCapabilities());
+ }
+ return capabilities;
+ }
}
diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java
index 921fa080cd..4a2f8e088a 100755
--- a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java
+++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -23,7 +23,7 @@ import org.junit.After;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
-import com.vaadin.tests.annotations.TestCategory;
+import com.vaadin.testbench.parallel.TestCategory;
@TestCategory("push")
public abstract class MultiBrowserTestWithProxy extends MultiBrowserTest {
diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java
index 15ca97f701..434eaca4d4 100644
--- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java
+++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java
@@ -1,12 +1,12 @@
/*
* Copyright 2000-2013 Vaadind 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
@@ -22,32 +22,31 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
-import java.util.Arrays;
import java.util.Enumeration;
import java.util.Properties;
-import org.openqa.selenium.WebDriver;
-import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.firefox.FirefoxBinary;
-import org.openqa.selenium.firefox.FirefoxDriver;
-import org.openqa.selenium.phantomjs.PhantomJSDriver;
-import org.openqa.selenium.remote.DesiredCapabilities;
-import org.openqa.selenium.safari.SafariDriver;
-
-import com.vaadin.testbench.TestBench;
-import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
+import com.vaadin.testbench.annotations.BrowserFactory;
+import com.vaadin.testbench.annotations.RunOnHub;
/**
* Provides values for parameters which depend on where the test is run.
* Parameters should be configured in work/eclipse-run-selected-test.properties.
* A template is available in uitest/.
- *
+ *
* @author Vaadin Ltd
*/
+@RunOnHub("tb3-hub.intra.itmill.com")
+@BrowserFactory(VaadinBrowserFactory.class)
public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
+ /**
+ *
+ */
+ public static final String SCREENSHOT_DIRECTORY = "com.vaadin.testbench.screenshot.directory";
private static final String RUN_LOCALLY_PROPERTY = "com.vaadin.testbench.runLocally";
private static final String HOSTNAME_PROPERTY = "com.vaadin.testbench.deployment.hostname";
private static final String PORT_PROPERTY = "com.vaadin.testbench.deployment.port";
+ private static final String DEPLOYMENT_PROPERTY = "com.vaadin.testbench.deployment.url";
+ private static final String HUB_URL = "com.vaadin.testbench.hub.url";
private static final Properties properties = new Properties();
private static final File propertiesFile = new File("work",
"eclipse-run-selected-test.properties");
@@ -61,7 +60,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
}
}
- private static String getProperty(String name) {
+ protected static String getProperty(String name) {
String property = properties.getProperty(name);
if (property == null) {
property = System.getProperty(name);
@@ -82,17 +81,32 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
@Override
protected String getScreenshotDirectory() {
- String screenshotDirectory = getProperty("com.vaadin.testbench.screenshot.directory");
+ String screenshotDirectory = getProperty(SCREENSHOT_DIRECTORY);
if (screenshotDirectory == null) {
throw new RuntimeException(
- "No screenshot directory defined. Use -Dcom.vaadin.testbench.screenshot.directory=<path>");
+ "No screenshot directory defined. Use -D"
+ + SCREENSHOT_DIRECTORY + "=<path>");
}
return screenshotDirectory;
}
@Override
- protected String getHubHostname() {
- return "tb3-hub.intra.itmill.com";
+ protected String getHubURL() {
+ String hubUrl = getProperty(HUB_URL);
+ if (hubUrl == null || hubUrl.trim().isEmpty()) {
+ return super.getHubURL();
+ }
+
+ return hubUrl;
+ }
+
+ @Override
+ protected String getBaseURL() {
+ String url = getProperty(DEPLOYMENT_PROPERTY);
+ if (url == null || url.trim().isEmpty()) {
+ return super.getBaseURL();
+ }
+ return url;
}
@Override
@@ -105,7 +119,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
/**
* Gets the hostname that tests are configured to use.
- *
+ *
* @return the host name configuration value
*/
public static String getConfiguredDeploymentHostname() {
@@ -125,7 +139,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
/**
* Gets the port that tests are configured to use.
- *
+ *
* @return the port configuration value
*/
public static int getConfiguredDeploymentPort() {
@@ -142,7 +156,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
/**
* Tries to automatically determine the IP address of the machine the test
* is running on.
- *
+ *
* @return An IP address of one of the network interfaces in the machine.
* @throws RuntimeException
* if there was an error or no IP was found
@@ -176,75 +190,4 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test {
throw new RuntimeException(
"No compatible (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) ip address found.");
}
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.tests.tb3.AbstractTB3Test#setupLocalDriver()
- */
- @Override
- protected void setupLocalDriver(DesiredCapabilities desiredCapabilities) {
- WebDriver driver;
- if (BrowserUtil.isFirefox(desiredCapabilities)) {
- String firefoxPath = getProperty("firefox.path");
- if (firefoxPath != null) {
- driver = new FirefoxDriver(new FirefoxBinary(new File(
- firefoxPath)), null);
- } else {
- driver = new FirefoxDriver();
- }
- } else if (BrowserUtil.isChrome(desiredCapabilities)) {
- String propertyName = "chrome.driver.path";
- String chromeDriverPath = getProperty(propertyName);
- if (chromeDriverPath == null) {
- throw new RuntimeException(
- "You need to install ChromeDriver to use @"
- + RunLocally.class.getSimpleName()
- + " with Chrome."
- + "\nFirst install it from https://code.google.com/p/selenium/wiki/ChromeDriver."
- + "\nThen update "
- + propertiesFile.getAbsolutePath()
- + " to define a property named "
- + propertyName
- + " containing the path of your local ChromeDriver installation.");
- }
- System.setProperty("webdriver.chrome.driver", chromeDriverPath);
- driver = new ChromeDriver();
- } else if (BrowserUtil.isSafari(desiredCapabilities)) {
- driver = new SafariDriver();
- } else if (BrowserUtil.isPhantomJS(desiredCapabilities)) {
- driver = new PhantomJSDriver();
- } else {
- throw new RuntimeException(
- "Not implemented support for running locally on "
- + BrowserUtil
- .getBrowserIdentifier(desiredCapabilities));
- }
- setDriver(TestBench.createDriver(driver));
- setDesiredCapabilities(desiredCapabilities);
- }
-
- @Override
- protected Browser getRunLocallyBrowser() {
- Browser runLocallyBrowser = super.getRunLocallyBrowser();
- if (runLocallyBrowser != null) {
- // Always use annotation value if present
- return runLocallyBrowser;
- }
-
- String runLocallyValue = getProperty(RUN_LOCALLY_PROPERTY);
- if (runLocallyValue == null || runLocallyValue.trim().isEmpty()) {
- return null;
- }
-
- String browserName = runLocallyValue.trim().toUpperCase();
- try {
- return Browser.valueOf(browserName);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException("Invalid " + RUN_LOCALLY_PROPERTY
- + " property from " + getSource(RUN_LOCALLY_PROPERTY)
- + ": " + runLocallyValue + ". Expected one of "
- + Arrays.toString(Browser.values()));
- }
- }
}
diff --git a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java
index 1782e0042e..d43befdb55 100644
--- a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java
+++ b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -16,36 +16,58 @@
package com.vaadin.tests.tb3;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileFilter;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-import javax.imageio.ImageIO;
-
+import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
-import org.openqa.selenium.OutputType;
-import org.openqa.selenium.TakesScreenshot;
+import org.junit.runner.Description;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.Parameters;
-import com.vaadin.testbench.commands.TestBenchCommands;
+import com.vaadin.testbench.ScreenshotOnFailureRule;
+import com.vaadin.testbench.parallel.BrowserUtil;
+import com.vaadin.testbench.screenshot.ImageFileUtil;
/**
* Base class which provides functionality for tests which use the automatic
* screenshot comparison function.
- *
+ *
* @author Vaadin Ltd
*/
public abstract class ScreenshotTB3Test extends AbstractTB3Test {
+ @Rule
+ public ScreenshotOnFailureRule screenshotOnFailure = new ScreenshotOnFailureRule(
+ this, true) {
+
+ @Override
+ protected void failed(Throwable throwable, Description description) {
+ super.failed(throwable, description);
+ closeApplication();
+ }
+
+ @Override
+ protected void succeeded(Description description) {
+ super.succeeded(description);
+ closeApplication();
+ }
+
+ @Override
+ protected File getErrorScreenshotFile(Description description) {
+ return ImageFileUtil
+ .getErrorScreenshotFile(getScreenshotFailureName());
+ };
+ };
+
private String screenshotBaseName;
@Rule
@@ -68,13 +90,15 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
* Contains a list of screenshot identifiers for which
* {@link #compareScreen(String)} has failed during the test
*/
- private List<String> screenshotFailures = new ArrayList<String>();
+ private List<String> screenshotFailures;
/**
* Defines TestBench screen comparison parameters before each test run
*/
@Before
public void setupScreenComparisonParameters() {
+ screenshotFailures = new ArrayList<String>();
+
Parameters.setScreenshotErrorDirectory(getScreenshotErrorDirectory());
Parameters
.setScreenshotReferenceDirectory(getScreenshotReferenceDirectory());
@@ -84,13 +108,13 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
* Grabs a screenshot and compares with the reference image with the given
* identifier. Supports alternative references and will succeed if the
* screenshot matches at least one of the references.
- *
+ *
* In case of a failed comparison this method stores the grabbed screenshots
* in the error directory as defined by
* {@link #getScreenshotErrorDirectory()}. It will also generate a html file
* in the same directory, comparing the screenshot with the first found
* reference.
- *
+ *
* @param identifier
* @throws IOException
*/
@@ -149,6 +173,27 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
deleteFailureFiles(failurePng);
}
}
+ if (referenceToKeep != null) {
+ File errorPng = getErrorFileFromReference(referenceToKeep);
+ enableAutoswitch(new File(errorPng.getParentFile(),
+ errorPng.getName() + ".html"));
+ }
+ }
+
+ private void enableAutoswitch(File htmlFile) throws FileNotFoundException,
+ IOException {
+ if (htmlFile == null || !htmlFile.exists()) {
+ return;
+ }
+
+ String html = FileUtils.readFileToString(htmlFile);
+
+ html = html.replace("body onclick=\"",
+ "body onclick=\"clearInterval(autoSwitch);");
+ html = html.replace("</script>",
+ ";autoSwitch=setInterval(switchImage,500);</script>");
+
+ FileUtils.writeStringToFile(htmlFile, html);
}
private void deleteFailureFiles(File failurePng) {
@@ -161,7 +206,7 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
/**
* Returns a new File which points to a .html file instead of the given .png
* file
- *
+ *
* @param png
* @return
*/
@@ -171,7 +216,7 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
}
/**
- *
+ *
* @param referenceFile
* The reference image file (in the directory defined by
* {@link #getScreenshotReferenceDirectory()})
@@ -180,14 +225,25 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
* given reference image fails.
*/
private File getErrorFileFromReference(File referenceFile) {
- return new File(referenceFile.getAbsolutePath().replace(
- getScreenshotReferenceDirectory(),
- getScreenshotErrorDirectory()));
+
+ String absolutePath = referenceFile.getAbsolutePath();
+ String screenshotReferenceDirectory = getScreenshotReferenceDirectory();
+ String screenshotErrorDirectory = getScreenshotErrorDirectory();
+ // We throw an exception to safeguard against accidental reference
+ // deletion. See (#14446)
+ if (!absolutePath.contains(screenshotReferenceDirectory)) {
+ throw new IllegalStateException(
+ "Reference screenshot not in reference directory. Screenshot path: '"
+ + absolutePath + "', directory path: '"
+ + screenshotReferenceDirectory + "'");
+ }
+ return new File(absolutePath.replace(screenshotReferenceDirectory,
+ screenshotErrorDirectory));
}
/**
* Finds alternative references for the given files
- *
+ *
* @param reference
* @return all references which should be considered when comparing with the
* given files, including the given reference
@@ -248,11 +304,23 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
protected abstract String getScreenshotDirectory();
/**
+ * @return the base directory of 'reference' and 'errors' screenshots with a
+ * trailing file separator
+ */
+ private String getScreenshotDirectoryWithTrailingSeparator() {
+ String screenshotDirectory = getScreenshotDirectory();
+ if (!screenshotDirectory.endsWith(File.separator)) {
+ screenshotDirectory += File.separator;
+ }
+ return screenshotDirectory;
+ }
+
+ /**
* @return the directory where reference images are stored (the 'reference'
* folder inside the screenshot directory)
*/
private String getScreenshotReferenceDirectory() {
- return getScreenshotDirectory() + "/reference";
+ return getScreenshotDirectoryWithTrailingSeparator() + "reference";
}
/**
@@ -260,13 +328,13 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
* (the 'errors' folder inside the screenshot directory)
*/
private String getScreenshotErrorDirectory() {
- return getScreenshotDirectory() + "/errors";
+ return getScreenshotDirectoryWithTrailingSeparator() + "errors";
}
/**
* Checks if any screenshot comparisons failures occurred during the test
* and combines all comparison errors into one exception
- *
+ *
* @throws IOException
* If there were failures during the test
*/
@@ -280,48 +348,15 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.tests.tb3.AbstractTB3Test#onUncaughtException(java.lang.Throwable
- * )
- */
- @Override
- public void onUncaughtException(Throwable cause) {
- super.onUncaughtException(cause);
- // Grab a "failure" screenshot and store in the errors folder for later
- // analysis
- try {
- TestBenchCommands testBench = testBench();
- if (testBench != null) {
- testBench.disableWaitForVaadin();
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
- try {
- if (driver != null) {
- BufferedImage screenshotImage = ImageIO
- .read(new ByteArrayInputStream(
- ((TakesScreenshot) driver)
- .getScreenshotAs(OutputType.BYTES)));
- ImageIO.write(screenshotImage, "png", new File(
- getScreenshotFailureName()));
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
-
- }
-
/**
* @return the name of a "failure" image which is stored in the folder
* defined by {@link #getScreenshotErrorDirectory()} when the test
* fails
*/
private String getScreenshotFailureName() {
- return getScreenshotErrorBaseName() + "-failure.png";
+ return getScreenshotBaseName() + "_"
+ + getUniqueIdentifier(getDesiredCapabilities())
+ + "-failure.png";
}
/**
@@ -334,7 +369,7 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
/**
* Returns the name of the reference file based on the given parameters.
- *
+ *
* @param testName
* @param capabilities
* @param identifier
@@ -348,7 +383,7 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
* Returns the name of the reference file based on the given parameters. The
* version given in {@literal capabilities} is used unless it is overridden
* by the {@literal versionOverride} parameter.
- *
+ *
* @param testName
* @param capabilities
* @param identifier
@@ -358,20 +393,53 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
Integer versionOverride) {
String uniqueBrowserIdentifier;
if (versionOverride == null) {
- uniqueBrowserIdentifier = BrowserUtil
- .getUniqueIdentifier(getDesiredCapabilities());
+ uniqueBrowserIdentifier = getUniqueIdentifier(getDesiredCapabilities());
} else {
- uniqueBrowserIdentifier = BrowserUtil.getUniqueIdentifier(
+ uniqueBrowserIdentifier = getUniqueIdentifier(
getDesiredCapabilities(), "" + versionOverride);
}
// WindowMaximizeRestoreTest_Windows_InternetExplorer_8_window-1-moved-maximized-restored.png
- return getScreenshotReferenceDirectory() + "/"
+ return getScreenshotReferenceDirectory() + File.separator
+ getScreenshotBaseName() + "_" + uniqueBrowserIdentifier + "_"
+ identifier + ".png";
}
/**
+ * Returns a string which uniquely (enough) identifies this browser. Used
+ * mainly in screenshot names.
+ *
+ * @param capabilities
+ * @param versionOverride
+ *
+ * @return a unique string for each browser
+ */
+ private String getUniqueIdentifier(DesiredCapabilities capabilities,
+ String versionOverride) {
+ return getUniqueIdentifier(BrowserUtil.getPlatform(capabilities),
+ BrowserUtil.getBrowserIdentifier(capabilities), versionOverride);
+ }
+
+ /**
+ * Returns a string which uniquely (enough) identifies this browser. Used
+ * mainly in screenshot names.
+ *
+ * @param capabilities
+ *
+ * @return a unique string for each browser
+ */
+ private String getUniqueIdentifier(DesiredCapabilities capabilities) {
+ return getUniqueIdentifier(BrowserUtil.getPlatform(capabilities),
+ BrowserUtil.getBrowserIdentifier(capabilities),
+ capabilities.getVersion());
+ }
+
+ private String getUniqueIdentifier(String platform, String browser,
+ String version) {
+ return platform + "_" + browser + "_" + version;
+ }
+
+ /**
* Returns the base name of the screenshot in the error directory. This is a
* name so that all files matching {@link #getScreenshotErrorBaseName()}*
* are owned by this test instance (taking into account
@@ -399,13 +467,12 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test {
errorDirectory.mkdirs();
}
- final String errorBase = getScreenshotErrorBaseName()
- .replace("\\", "/");
+ final String errorBase = getScreenshotErrorBaseName();
File[] files = errorDirectory.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
- String thisFile = pathname.getAbsolutePath().replace("\\", "/");
+ String thisFile = pathname.getAbsolutePath();
if (thisFile.startsWith(errorBase)) {
return true;
}
diff --git a/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java b/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java
index 294d012be5..c884f69bd1 100644
--- a/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java
+++ b/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -16,6 +16,8 @@
package com.vaadin.tests.tb3;
+import java.io.IOException;
+
import org.junit.runner.RunWith;
import org.junit.runners.model.InitializationError;
@@ -27,7 +29,7 @@ public class ServletIntegrationTests {
public static class ServletIntegrationTestSuite extends TB3TestSuite {
public ServletIntegrationTestSuite(Class<?> klass)
- throws InitializationError {
+ throws InitializationError, IOException {
super(klass, AbstractServletIntegrationTest.class,
"com.vaadin.tests.integration", new String[] {});
}
diff --git a/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java
new file mode 100644
index 0000000000..ffb57b5b47
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java
@@ -0,0 +1,31 @@
+/*
+ * 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.tb3;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.parallel.Browser;
+
+public abstract class SingleBrowserTest extends PrivateTB3Configuration {
+ @Override
+ public List<DesiredCapabilities> getBrowsersToTest() {
+ return Collections.singletonList(Browser.PHANTOMJS
+ .getDesiredCapabilities());
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java
index e1693e50d7..23a6370572 100644
--- a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java
+++ b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java
@@ -16,34 +16,16 @@
package com.vaadin.tests.tb3;
-import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runners.BlockJUnit4ClassRunner;
+import org.apache.http.client.HttpClient;
import org.junit.runners.Parameterized;
-import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.internal.HttpClientFactory;
-import com.vaadin.tests.annotations.TestCategory;
-import com.vaadin.tests.tb3.AbstractTB3Test.BrowserUtil;
-import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
+import com.vaadin.testbench.parallel.ParallelRunner;
/**
* This runner is loosely based on FactoryTestRunner by Ted Young
@@ -53,33 +35,16 @@ import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
*
* @since 7.1
*/
-public class TB3Runner extends BlockJUnit4ClassRunner {
+public class TB3Runner extends ParallelRunner {
/**
* Socket timeout for HTTP connections to the grid hub. The connection is
- * closed after 15 minutes of inactivity to avoid builds hanging for up to
+ * closed after 30 minutes of inactivity to avoid builds hanging for up to
* three hours per connection if the test client crashes/hangs.
*/
- private static final int SOCKET_TIMEOUT = 15 * 60 * 1000;
-
- /**
- * This is the total limit of actual JUnit test instances run in parallel
- */
- private static final int MAX_CONCURRENT_TESTS;
-
- /**
- * This is static so it is shared by all tests running concurrently on the
- * same machine and thus can limit the number of threads in use.
- */
- private static final ExecutorService service;
+ private static final int SOCKET_TIMEOUT = 30 * 60 * 1000;
static {
- if (System.getProperty("useLocalWebDriver") != null) {
- MAX_CONCURRENT_TESTS = 10;
- } else {
- MAX_CONCURRENT_TESTS = 50;
- }
- service = Executors.newFixedThreadPool(MAX_CONCURRENT_TESTS);
// reduce socket timeout to avoid tests hanging for three hours
try {
@@ -89,11 +54,16 @@ public class TB3Runner extends BlockJUnit4ClassRunner {
field.setAccessible(true);
field.set(null, new HttpClientFactory() {
@Override
- public HttpParams getHttpParams() {
- HttpParams params = super.getHttpParams();
- // fifteen minute timeout
- HttpConnectionParams.setSoTimeout(params, SOCKET_TIMEOUT);
- return params;
+ public HttpClient getGridHttpClient(int connection_timeout,
+ int socket_timeout) {
+
+ if (socket_timeout == 0 || socket_timeout > SOCKET_TIMEOUT) {
+ return super.getGridHttpClient(connection_timeout,
+ SOCKET_TIMEOUT);
+ }
+
+ return super.getGridHttpClient(connection_timeout,
+ socket_timeout);
}
});
} catch (Exception e) {
@@ -103,311 +73,8 @@ public class TB3Runner extends BlockJUnit4ClassRunner {
}
}
- protected static boolean localWebDriverIsUsed() {
- String useLocalWebDriver = System.getProperty("useLocalWebDriver");
-
- return useLocalWebDriver != null
- && useLocalWebDriver.toLowerCase().equals("true");
- }
-
public TB3Runner(Class<?> klass) throws InitializationError {
super(klass);
- setScheduler(new ParallelScheduler(service));
- }
-
- @Override
- protected List<FrameworkMethod> computeTestMethods() {
- List<FrameworkMethod> tests = new LinkedList<FrameworkMethod>();
-
- if (!AbstractTB3Test.class.isAssignableFrom(getTestClass()
- .getJavaClass())) {
- throw new RuntimeException(getClass().getName() + " only supports "
- + AbstractTB3Test.class.getName());
- }
-
- try {
- AbstractTB3Test testClassInstance = getTestClassInstance();
- Collection<DesiredCapabilities> desiredCapabilities = getDesiredCapabilities(testClassInstance);
-
- TestNameSuffix testNameSuffixProperty = findAnnotation(
- testClassInstance.getClass(), TestNameSuffix.class);
-
- for (FrameworkMethod m : getTestMethods()) {
- // No browsers available for this test, so we need to
- // wrap the test method inside IgnoredTestMethod.
- // This will add @Ignore annotation to it.
- if (desiredCapabilities.size() <= 0
- || categoryIsExcludedOrNotExcplicitlyIncluded()) {
- tests.add(new IgnoredTestMethod(m.getMethod()));
- } else {
- for (DesiredCapabilities capabilities : desiredCapabilities) {
- TB3Method method = new TB3Method(m.getMethod(),
- capabilities);
- if (testNameSuffixProperty != null) {
- method.setTestNameSuffix("-"
- + System.getProperty(testNameSuffixProperty
- .property()));
- }
- tests.add(method);
- }
- }
- }
- } catch (Exception e) {
- throw new RuntimeException("Error retrieving browsers to run on", e);
- }
-
- return tests;
- }
-
- private boolean categoryIsExcludedOrNotExcplicitlyIncluded() {
- Class<?> c = getTestClass().getJavaClass();
-
- if (categoryIsExcluded(c)) {
- return true;
- }
-
- if (explicitInclusionIsUsed()) {
- return !categoryIsIncluded(c);
- }
-
- return false;
- }
-
- private boolean categoryIsIncluded(Class<?> c) {
- String include = System.getProperty("categories.include");
- if (include != null && include.trim().length() > 0) {
- return hasCategoryFor(c, include.toLowerCase().trim());
- }
-
- return false;
- }
-
- private static boolean explicitInclusionIsUsed() {
- String include = System.getProperty("categories.include");
-
- return include != null && include.trim().length() > 0;
- }
-
- private static boolean categoryIsExcluded(Class<?> c) {
- String exclude = System.getProperty("categories.exclude");
- if (exclude != null && exclude.trim().length() > 0) {
- return hasCategoryFor(c, exclude.toLowerCase().trim());
- }
-
- return false;
- }
-
- private static boolean hasCategoryFor(Class<?> c, String searchString) {
- if (hasCategory(c)) {
- return searchString.contains(getCategory(c).toLowerCase());
- }
-
- return false;
- }
-
- private static boolean hasCategory(Class<?> c) {
- return c.getAnnotation(TestCategory.class) != null;
- }
-
- private static String getCategory(Class<?> c) {
- return c.getAnnotation(TestCategory.class).value();
- }
-
- private List<FrameworkMethod> getTestMethods() {
- return getTestClass().getAnnotatedMethods(Test.class);
- }
-
- /*
- * Returns a list of desired browser capabilities according to browsers
- * defined in the test class, filtered by possible filter parameters. Use
- * {@code @RunLocally} annotation or com.vaadin.testbench.runLocally
- * property to override all capabilities.
- */
- private Collection<DesiredCapabilities> getDesiredCapabilities(
- AbstractTB3Test testClassInstance) {
- Collection<DesiredCapabilities> desiredCapabilites = getFilteredCapabilities(testClassInstance);
-
- Browser runLocallyBrowser = testClassInstance.getRunLocallyBrowser();
- if (runLocallyBrowser != null) {
- desiredCapabilites = new ArrayList<DesiredCapabilities>();
- desiredCapabilites.add(runLocallyBrowser.getDesiredCapabilities());
- }
-
- return desiredCapabilites;
- }
-
- /*
- * Takes the desired browser capabilities defined in the test class and
- * returns a list of browser capabilities filtered browsers.include and
- * browsers.exclude system properties. (if present)
- */
- private Collection<DesiredCapabilities> getFilteredCapabilities(
- AbstractTB3Test testClassInstance) {
- Collection<DesiredCapabilities> desiredCapabilites = testClassInstance
- .getBrowsersToTest();
-
- ArrayList<DesiredCapabilities> filteredCapabilities = new ArrayList<DesiredCapabilities>();
-
- String include = System.getProperty("browsers.include");
- String exclude = System.getProperty("browsers.exclude");
-
- for (DesiredCapabilities d : desiredCapabilites) {
- String browserName = (d.getBrowserName() + d.getVersion())
- .toLowerCase();
- if (include != null && include.trim().length() > 0) {
- if (include.trim().toLowerCase().contains(browserName)) {
- filteredCapabilities.add(d);
- }
- } else {
- filteredCapabilities.add(d);
- }
-
- if (exclude != null && exclude.trim().length() > 0) {
- if (exclude.trim().toLowerCase().contains(browserName)) {
- filteredCapabilities.remove(d);
- }
- }
-
- }
- return filteredCapabilities;
- }
-
- private AbstractTB3Test getTestClassInstance()
- throws InstantiationException, IllegalAccessException,
- InvocationTargetException {
- AbstractTB3Test testClassInstance = (AbstractTB3Test) getTestClass()
- .getOnlyConstructor().newInstance();
- return testClassInstance;
- }
-
- // This is a FrameworkMethod class that will always
- // return @Ignore and @Test annotations for the wrapped method.
- private class IgnoredTestMethod extends FrameworkMethod {
-
- private class IgnoreTestAnnotations {
-
- // We use this method to easily get our hands on
- // the Annotation instances for @Ignore and @Test
- @Ignore
- @Test
- public void ignoredTest() {
- }
- }
-
- public IgnoredTestMethod(Method method) {
- super(method);
- }
-
- @Override
- public Annotation[] getAnnotations() {
- return getIgnoredTestMethod().getAnnotations();
- }
-
- private Method getIgnoredTestMethod() {
- try {
- return IgnoreTestAnnotations.class.getMethod("ignoredTest",
- null);
- } catch (Exception e) {
- return null;
- }
-
- }
-
- @Override
- public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
- return getIgnoredTestMethod().getAnnotation(annotationType);
- }
- }
-
- /**
- * Finds the given annotation in the given class or one of its super
- * classes. Return the first found annotation
- *
- * @param searchClass
- * @param annotationClass
- * @return
- */
- private <T extends Annotation> T findAnnotation(Class<?> searchClass,
- Class<T> annotationClass) {
- if (searchClass == Object.class) {
- return null;
- }
-
- if (searchClass.getAnnotation(annotationClass) != null) {
- return searchClass.getAnnotation(annotationClass);
- }
-
- return findAnnotation(searchClass.getSuperclass(), annotationClass);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.junit.runners.BlockJUnit4ClassRunner#withBefores(org.junit.runners
- * .model.FrameworkMethod, java.lang.Object,
- * org.junit.runners.model.Statement)
- */
- @Override
- protected Statement withBefores(final FrameworkMethod method,
- final Object target, Statement statement) {
- if (!(method instanceof TB3Method)) {
- throw new RuntimeException("Unexpected method type "
- + method.getClass().getName() + ", expected TB3Method");
- }
- final TB3Method tb3method = (TB3Method) method;
-
- // setDesiredCapabilities before running the real @Befores (which use
- // capabilities)
-
- final Statement realBefores = super.withBefores(method, target,
- statement);
- return new Statement() {
-
- @Override
- public void evaluate() throws Throwable {
- ((AbstractTB3Test) target)
- .setDesiredCapabilities(tb3method.capabilities);
- try {
- realBefores.evaluate();
- } catch (Throwable t) {
- // Give the test a chance to e.g. produce an error
- // screenshot before failing the test by re-throwing the
- // exception
- ((AbstractTB3Test) target).onUncaughtException(t);
- throw t;
- }
- }
- };
- }
-
- private static class TB3Method extends FrameworkMethod {
- private DesiredCapabilities capabilities;
- private String testNameSuffix = "";
-
- public TB3Method(Method method, DesiredCapabilities capabilities) {
- super(method);
- this.capabilities = capabilities;
- }
-
- public void setTestNameSuffix(String testNameSuffix) {
- this.testNameSuffix = testNameSuffix;
- }
-
- @Override
- public Object invokeExplosively(final Object target, Object... params)
- throws Throwable {
- // Executes the test method with the supplied parameters
- return super.invokeExplosively(target);
- }
-
- @Override
- public String getName() {
- return String.format("%s[%s]", getMethod().getName()
- + testNameSuffix,
- BrowserUtil.getUniqueIdentifier(capabilities));
- }
-
}
}
diff --git a/uitest/src/com/vaadin/tests/tb3/TB3TestLocator.java b/uitest/src/com/vaadin/tests/tb3/TB3TestLocator.java
new file mode 100644
index 0000000000..b102309fc1
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/TB3TestLocator.java
@@ -0,0 +1,218 @@
+/*
+ * 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.tb3;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.net.JarURLConnection;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+
+public class TB3TestLocator {
+ /**
+ * Traverses the directory on the classpath (inside or outside a Jar file)
+ * specified by 'basePackage'. Collects all classes inside the location
+ * which can be assigned to 'baseClass' except for classes inside packages
+ * listed in 'ignoredPackages'.
+ *
+ * @param baseClass
+ * @param basePackage
+ * @param ignorePackages
+ * @return
+ */
+ public Class<?>[] findTests(Class<? extends AbstractTB3Test> baseClass,
+ String basePackage, String[] ignorePackages) {
+ try {
+ List<?> l = findClasses(baseClass, basePackage, ignorePackages);
+ return l.toArray(new Class[] {});
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Traverses the directory on the classpath (inside or outside a Jar file)
+ * specified by 'basePackage'. Collects all classes inside the location
+ * which can be assigned to 'baseClass' except for classes inside packages
+ * listed in 'ignoredPackages'.
+ *
+ * @param baseClass
+ * @param basePackage
+ * @param ignoredPackages
+ * @return
+ * @throws IOException
+ */
+ protected <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
+ String basePackage, String[] ignoredPackages) throws IOException {
+ List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
+ String basePackageDirName = "/" + basePackage.replace('.', '/');
+ URL location = baseClass.getResource(basePackageDirName);
+ if (location.getProtocol().equals("file")) {
+ try {
+ File f = new File(location.toURI());
+ if (!f.exists()) {
+ throw new IOException("Directory " + f.toString()
+ + " does not exist");
+ }
+ findPackages(f, basePackage, baseClass, classes,
+ ignoredPackages);
+ } catch (URISyntaxException e) {
+ throw new IOException(e.getMessage());
+ }
+ } else if (location.getProtocol().equals("jar")) {
+ JarURLConnection juc = (JarURLConnection) location.openConnection();
+ findClassesInJar(juc, basePackage, baseClass, classes);
+ }
+
+ Collections.sort(classes, new Comparator<Class<? extends T>>() {
+
+ @Override
+ public int compare(Class<? extends T> o1, Class<? extends T> o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+
+ });
+
+ return classes;
+ }
+
+ /**
+ * Traverses the given directory and collects all classes which are inside
+ * the given 'javaPackage' and can be assigned to the given 'baseClass'. The
+ * found classes are added to 'result'.
+ *
+ * @param parent
+ * The directory to traverse
+ * @param javaPackage
+ * The java package which 'parent' contains
+ * @param baseClass
+ * The class which the target classes extend
+ * @param result
+ * The collection to which found classes are added
+ * @param ignoredPackages
+ * A collection of packages (including sub packages) to ignore
+ */
+ private <T> void findPackages(File parent, String javaPackage,
+ Class<T> baseClass, Collection<Class<? extends T>> result,
+ String[] ignoredPackages) {
+ for (String ignoredPackage : ignoredPackages) {
+ if (javaPackage.equals(ignoredPackage)) {
+ return;
+ }
+ }
+
+ for (File file : parent.listFiles()) {
+ if (file.isDirectory()) {
+ findPackages(file, javaPackage + "." + file.getName(),
+ baseClass, result, ignoredPackages);
+ } else if (file.getName().endsWith(".class")) {
+ String fullyQualifiedClassName = javaPackage + "."
+ + file.getName().replace(".class", "");
+ addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+ }
+ }
+
+ }
+
+ /**
+ * Traverses a Jar file using the given connection and collects all classes
+ * which are inside the given 'javaPackage' and can be assigned to the given
+ * 'baseClass'. The found classes are added to 'result'.
+ *
+ * @param javaPackage
+ * The java package containing the classes (classes may be in a
+ * sub package)
+ * @param baseClass
+ * The class which the target classes extend
+ * @param result
+ * The collection to which found classes are added
+ * @throws IOException
+ */
+ private <T> void findClassesInJar(JarURLConnection juc, String javaPackage,
+ Class<T> baseClass, Collection<Class<? extends T>> result)
+ throws IOException {
+ String javaPackageDir = javaPackage.replace('.', '/');
+ Enumeration<JarEntry> ent = juc.getJarFile().entries();
+ while (ent.hasMoreElements()) {
+ JarEntry e = ent.nextElement();
+ if (e.getName().endsWith(".class")
+ && e.getName().startsWith(javaPackageDir)) {
+ String fullyQualifiedClassName = e.getName().replace('/', '.')
+ .replace(".class", "");
+ addClassIfMatches(result, fullyQualifiedClassName, baseClass);
+ }
+ }
+ }
+
+ /**
+ * Verifies that the class represented by 'fullyQualifiedClassName' can be
+ * loaded, assigned to 'baseClass' and is not an abstract or anonymous
+ * class.
+ *
+ * @param result
+ * The collection to add to
+ * @param fullyQualifiedClassName
+ * The candidate class
+ * @param baseClass
+ * The class 'fullyQualifiedClassName' should be assignable to
+ */
+ @SuppressWarnings("unchecked")
+ protected <T> void addClassIfMatches(Collection<Class<? extends T>> result,
+ String fullyQualifiedClassName, Class<T> baseClass) {
+ try {
+ // Try to load the class
+
+ Class<?> c = Class.forName(fullyQualifiedClassName);
+ if (!baseClass.isAssignableFrom(c)) {
+ return;
+ }
+ if (!includeInSuite(c)) {
+ return;
+ }
+
+ if (!Modifier.isAbstract(c.getModifiers()) && !c.isAnonymousClass()) {
+ result.add((Class<? extends T>) c);
+ }
+ } catch (Exception e) {
+ // Could ignore that class cannot be loaded
+ e.printStackTrace();
+ } catch (LinkageError e) {
+ // Ignore. Client side classes will at least throw LinkageErrors
+ }
+
+ }
+
+ /**
+ * @return true if the class should be included in the suite, false if not
+ */
+ private boolean includeInSuite(Class<?> c) {
+ if (c.getAnnotation(ExcludeFromSuite.class) != null) {
+ return false;
+ }
+
+ return true;
+ }
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
index 703d01c122..8f6a29d275 100644
--- a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
+++ b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java
@@ -1,252 +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.tb3;
-import java.io.File;
import java.io.IOException;
-import java.lang.reflect.Modifier;
-import java.net.JarURLConnection;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.jar.JarEntry;
-import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
+import com.vaadin.testbench.parallel.ParallelTestSuite;
+
/**
* Test suite which consists of all the TB3 tests passed in the constructor.
* Runs the tests in parallel using a {@link ParallelScheduler}
- *
+ *
* @author Vaadin Ltd
*/
-public class TB3TestSuite extends Suite {
-
- /**
- * This only restricts the number of test suites running concurrently. The
- * number of tests to run concurrently are configured in {@link TB3Runner}.
- */
- private static final int MAX_CONCURRENT_TEST_SUITES = 20;
-
- /**
- * This is static so it is shared by all test suites running concurrently on
- * the same machine and thus can limit the number of threads in use.
- */
- private final ExecutorService service = Executors
- .newFixedThreadPool(MAX_CONCURRENT_TEST_SUITES);
-
+public class TB3TestSuite extends ParallelTestSuite {
public TB3TestSuite(Class<?> klass,
Class<? extends AbstractTB3Test> baseClass, String basePackage,
- String[] ignorePackages) throws InitializationError {
- super(klass, findTests(baseClass, basePackage, ignorePackages));
- setScheduler(new ParallelScheduler(service));
+ String[] ignorePackages) throws InitializationError, IOException {
+ this(klass, baseClass, basePackage, ignorePackages,
+ new TB3TestLocator());
}
- /**
- * Traverses the directory on the classpath (inside or outside a Jar file)
- * specified by 'basePackage'. Collects all classes inside the location
- * which can be assigned to 'baseClass' except for classes inside packages
- * listed in 'ignoredPackages'.
- *
- * @param baseClass
- * @param basePackage
- * @param ignorePackages
- * @return
- */
- private static Class<?>[] findTests(
+ public TB3TestSuite(Class<?> klass,
Class<? extends AbstractTB3Test> baseClass, String basePackage,
- String[] ignorePackages) {
- try {
- List<?> l = findClasses(baseClass, basePackage, ignorePackages);
- return l.toArray(new Class[] {});
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * Traverses the directory on the classpath (inside or outside a Jar file)
- * specified by 'basePackage'. Collects all classes inside the location
- * which can be assigned to 'baseClass' except for classes inside packages
- * listed in 'ignoredPackages'.
- *
- * @param baseClass
- * @param basePackage
- * @param ignoredPackages
- * @return
- * @throws IOException
- */
- private static <T> List<Class<? extends T>> findClasses(Class<T> baseClass,
- String basePackage, String[] ignoredPackages) throws IOException {
- List<Class<? extends T>> classes = new ArrayList<Class<? extends T>>();
- String basePackageDirName = "/" + basePackage.replace('.', '/');
- URL location = baseClass.getResource(basePackageDirName);
- if (location.getProtocol().equals("file")) {
- try {
- File f = new File(location.toURI());
- if (!f.exists()) {
- throw new IOException("Directory " + f.toString()
- + " does not exist");
- }
- findPackages(f, basePackage, baseClass, classes,
- ignoredPackages);
- } catch (URISyntaxException e) {
- throw new IOException(e.getMessage());
- }
- } else if (location.getProtocol().equals("jar")) {
- JarURLConnection juc = (JarURLConnection) location.openConnection();
- findClassesInJar(juc, basePackage, baseClass, classes);
- }
-
- Collections.sort(classes, new Comparator<Class<? extends T>>() {
-
- @Override
- public int compare(Class<? extends T> o1, Class<? extends T> o2) {
- return o1.getName().compareTo(o2.getName());
- }
-
- });
- return classes;
- }
-
- /**
- * Traverses the given directory and collects all classes which are inside
- * the given 'javaPackage' and can be assigned to the given 'baseClass'. The
- * found classes are added to 'result'.
- *
- * @param parent
- * The directory to traverse
- * @param javaPackage
- * The java package which 'parent' contains
- * @param baseClass
- * The class which the target classes extend
- * @param result
- * The collection to which found classes are added
- * @param ignoredPackages
- * A collection of packages (including sub packages) to ignore
- */
- private static <T> void findPackages(File parent, String javaPackage,
- Class<T> baseClass, Collection<Class<? extends T>> result,
- String[] ignoredPackages) {
- for (String ignoredPackage : ignoredPackages) {
- if (javaPackage.equals(ignoredPackage)) {
- return;
- }
- }
-
- for (File file : parent.listFiles()) {
- if (file.isDirectory()) {
- findPackages(file, javaPackage + "." + file.getName(),
- baseClass, result, ignoredPackages);
- } else if (file.getName().endsWith(".class")) {
- String fullyQualifiedClassName = javaPackage + "."
- + file.getName().replace(".class", "");
- addClassIfMatches(result, fullyQualifiedClassName, baseClass);
- }
- }
-
- }
-
- /**
- * Traverses a Jar file using the given connection and collects all classes
- * which are inside the given 'javaPackage' and can be assigned to the given
- * 'baseClass'. The found classes are added to 'result'.
- *
- * @param javaPackage
- * The java package containing the classes (classes may be in a
- * sub package)
- * @param baseClass
- * The class which the target classes extend
- * @param result
- * The collection to which found classes are added
- * @throws IOException
- */
- private static <T> void findClassesInJar(JarURLConnection juc,
- String javaPackage, Class<T> baseClass,
- Collection<Class<? extends T>> result) throws IOException {
- String javaPackageDir = javaPackage.replace('.', '/');
- Enumeration<JarEntry> ent = juc.getJarFile().entries();
- while (ent.hasMoreElements()) {
- JarEntry e = ent.nextElement();
- if (e.getName().endsWith(".class")
- && e.getName().startsWith(javaPackageDir)) {
- String fullyQualifiedClassName = e.getName().replace('/', '.')
- .replace(".class", "");
- addClassIfMatches(result, fullyQualifiedClassName, baseClass);
- }
- }
- }
-
- /**
- * Verifies that the class represented by 'fullyQualifiedClassName' can be
- * loaded, assigned to 'baseClass' and is not an abstract or anonymous
- * class.
- *
- * @param result
- * The collection to add to
- * @param fullyQualifiedClassName
- * The candidate class
- * @param baseClass
- * The class 'fullyQualifiedClassName' should be assignable to
- */
- @SuppressWarnings("unchecked")
- private static <T> void addClassIfMatches(
- Collection<Class<? extends T>> result,
- String fullyQualifiedClassName, Class<T> baseClass) {
- try {
- // Try to load the class
-
- Class<?> c = Class.forName(fullyQualifiedClassName);
- if (!baseClass.isAssignableFrom(c)) {
- return;
- }
- if (!includeInSuite(c)) {
- return;
- }
-
- if (!Modifier.isAbstract(c.getModifiers()) && !c.isAnonymousClass()) {
- result.add((Class<? extends T>) c);
- }
- } catch (Exception e) {
- // Could ignore that class cannot be loaded
- e.printStackTrace();
- } catch (LinkageError e) {
- // Ignore. Client side classes will at least throw LinkageErrors
- }
-
- }
-
- /**
- * @return true if the class should be included in the suite, false if not
- */
- private static boolean includeInSuite(Class<?> c) {
- if (c.getAnnotation(ExcludeFromSuite.class) != null) {
- return false;
- }
-
- return true;
+ String[] ignorePackages, TB3TestLocator locator)
+ throws InitializationError, IOException {
+ super(klass, locator
+ .findClasses(baseClass, basePackage, ignorePackages).toArray(
+ new Class<?>[] {}));
}
-}
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/tb3/VaadinBrowserFactory.java b/uitest/src/com/vaadin/tests/tb3/VaadinBrowserFactory.java
new file mode 100644
index 0000000000..d3e02d378d
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/tb3/VaadinBrowserFactory.java
@@ -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.tb3;
+
+import org.openqa.selenium.Platform;
+import org.openqa.selenium.ie.InternetExplorerDriver;
+import org.openqa.selenium.remote.DesiredCapabilities;
+
+import com.vaadin.testbench.parallel.Browser;
+import com.vaadin.testbench.parallel.DefaultBrowserFactory;
+
+public class VaadinBrowserFactory extends DefaultBrowserFactory {
+
+ @Override
+ public DesiredCapabilities create(Browser browser) {
+ switch (browser) {
+ case IE8:
+ return createIE(browser, "8");
+ case IE9:
+ return createIE(browser, "9");
+ case IE10:
+ return createIE(browser, "10");
+ case IE11:
+ return createIE(browser, "11");
+ case PHANTOMJS:
+ return create(browser, "1", Platform.LINUX);
+ case CHROME:
+ return create(browser, "40", Platform.VISTA);
+ case FIREFOX:
+ default:
+ return create(browser, "24", Platform.XP);
+ }
+ }
+
+ private DesiredCapabilities createIE(Browser browser, String version) {
+ DesiredCapabilities capabilities = create(browser, version,
+ Platform.WINDOWS);
+ capabilities.setCapability(
+ InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, true);
+ return capabilities;
+ }
+
+ @Override
+ public DesiredCapabilities create(Browser browser, String version) {
+ return create(browser);
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java b/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java
index 778c8b9113..df95b1b087 100644
--- a/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java
+++ b/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java
@@ -1,64 +1,39 @@
/*
* Copyright 2000-2014 Vaadin Ltd.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
-
/**
- *
+ *
*/
package com.vaadin.tests.tb3;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import org.openqa.selenium.remote.DesiredCapabilities;
-import com.vaadin.tests.annotations.TestCategory;
-import com.vaadin.tests.tb3.MultiBrowserTest.Browser;
+import com.vaadin.testbench.parallel.TestCategory;
/**
* A {@link MultiBrowserTest} which restricts the tests to the browsers which
* support websocket
- *
+ *
* @author Vaadin Ltd
*/
@TestCategory("push")
-public abstract class WebsocketTest extends PrivateTB3Configuration {
- private static List<DesiredCapabilities> websocketBrowsers = new ArrayList<DesiredCapabilities>();
- static {
- websocketBrowsers.addAll(MultiBrowserTest.getAllBrowsers());
- websocketBrowsers.remove(Browser.IE8.getDesiredCapabilities());
- websocketBrowsers.remove(Browser.IE9.getDesiredCapabilities());
- websocketBrowsers.remove(Browser.PHANTOMJS.getDesiredCapabilities());
- }
-
- /**
- * @return All supported browsers which are actively tested and support
- * websockets
- */
- public static List<DesiredCapabilities> getWebsocketBrowsers() {
- return Collections.unmodifiableList(websocketBrowsers);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see com.vaadin.tests.tb3.AbstractTB3Test#getBrowserToRunOn()
- */
+public abstract class WebsocketTest extends MultiBrowserTest {
@Override
public List<DesiredCapabilities> getBrowsersToTest() {
- return new ArrayList<DesiredCapabilities>(getWebsocketBrowsers());
+ return getBrowsersSupportingWebSocket();
}
-}
+} \ No newline at end of file
diff --git a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java
index d27884a13a..b2aec030a5 100644
--- a/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java
+++ b/uitest/src/com/vaadin/tests/widgetset/server/gwtrpc/GwtRpcTest.java
@@ -36,7 +36,7 @@ public class GwtRpcTest extends MultiBrowserTest {
By label = By.id(GwtRpcButtonConnector.SUCCESS_LABEL_ID);
- waitForElementToBePresent(label);
+ waitForElementPresent(label);
getDriver().findElement(label);
}
diff --git a/uitest/tb3test.xml b/uitest/tb3test.xml
index 6e0f25a8f7..edf1283f64 100644
--- a/uitest/tb3test.xml
+++ b/uitest/tb3test.xml
@@ -1,45 +1,43 @@
<?xml version="1.0"?>
<project name="tb3test" xmlns:antcontrib="antlib:net.sf.antcontrib" xmlns:ivy="antlib:org.apache.ivy.ant" basedir=".">
-
- <dirname property="tb3test.dir" file="${ant.file.tb3test}" />
- <property name="report.dir" location="${tb3test.dir}/result/reports-tb3" />
- <property name="browsers.include" value="" />
- <property name="browsers.exclude" value="" />
- <property name="categories.include" value="" />
- <property name="categories.exclude" value="" />
-
- <ivy:resolve file="${tb3test.dir}/ivy.xml" conf="build, build-provided" />
- <ivy:cachepath pathid="classpath.tb3.lib" conf="build, build-provided" />
- <path id="classpath.tb3">
- <path refid="classpath.tb3.lib" />
- <path location="${tb3test.dir}/result/classes" />
- </path>
-
- <target name="run-all-tb3-tests" unless="tests.tb3.skip" description="Run all the TB3 tests (except server tests) in the project">
- <antcall target="run-tb3-suite">
- <param name="junit.test.suite" value="com.vaadin.tests.tb3.AllTB3Tests" />
- </antcall>
- </target>
-
- <target name="run-tb3-suite">
- <fail unless="junit.test.suite" message="Define suite to run using junit.test.suite" />
- <fail unless="com.vaadin.testbench.screenshot.directory" message="Define screenshot directory using -Dcom.vaadin.testbench.screenshot.directory" />
- <delete dir="${report.dir}" />
- <mkdir dir="${report.dir}" />
-
- <junit showoutput="no" printsummary="no" fork="yes">
- <formatter type="xml" />
- <classpath refid="classpath.tb3" />
-
- <jvmarg value="-Dcom.vaadin.testbench.screenshot.directory=${com.vaadin.testbench.screenshot.directory}" />
- <jvmarg value="-Djava.awt.headless=true" />
- <jvmarg value="-Dbrowsers.include=${browsers.include}" />
- <jvmarg value="-Dbrowsers.exclude=${browsers.exclude}" />
- <jvmarg value="-Dcategories.include=${categories.include}" />
- <jvmarg value="-Dcategories.exclude=${categories.exclude}" />
- <test name="${junit.test.suite}" todir="${report.dir}" />
- </junit>
-
- </target>
-
-</project>
+ <dirname property="tb3test.dir" file="${ant.file.tb3test}" />
+ <property name="report.dir" location="${tb3test.dir}/result/reports-tb3" />
+ <property name="browsers.include" value="" />
+ <property name="browsers.exclude" value="" />
+ <property name="categories.include" value="" />
+ <property name="categories.exclude" value="" />
+ <property name="useLocalWebDriver" value="false" />
+ <property name="com.vaadin.testbench.max.retries" value="0" />
+ <property name="com.vaadin.testbench.hub.url" value="" />
+ <property name="vaadin.testbench.developer.license" value="" />
+ <property name="junit.test.suite" value="com.vaadin.tests.tb3.AllTB3Tests" />
+ <ivy:resolve file="${tb3test.dir}/ivy.xml" conf="build, build-provided" />
+ <ivy:cachepath pathid="classpath.tb3.lib" conf="build, build-provided" />
+ <path id="classpath.tb3">
+ <path refid="classpath.tb3.lib" />
+ <path location="${tb3test.dir}/result/classes" />
+ </path>
+ <target name="run-all-tb3-tests" unless="tests.tb3.skip" description="Run all the TB3 tests (except server tests) in the project">
+ <antcall target="run-tb3-suite" />
+ </target>
+ <target name="run-tb3-suite">
+ <fail unless="com.vaadin.testbench.screenshot.directory" message="Define screenshot directory using -Dcom.vaadin.testbench.screenshot.directory" />
+ <delete dir="${report.dir}" />
+ <mkdir dir="${report.dir}" />
+ <junit showoutput="no" printsummary="no" fork="yes">
+ <formatter type="xml" />
+ <classpath refid="classpath.tb3" />
+ <jvmarg value="-Dcom.vaadin.testbench.screenshot.directory=${com.vaadin.testbench.screenshot.directory}" />
+ <jvmarg value="-Djava.awt.headless=true" />
+ <jvmarg value="-Dbrowsers.include=${browsers.include}" />
+ <jvmarg value="-Dbrowsers.exclude=${browsers.exclude}" />
+ <jvmarg value="-Dcategories.include=${categories.include}" />
+ <jvmarg value="-Dcategories.exclude=${categories.exclude}" />
+ <jvmarg value="-DuseLocalWebDriver=${useLocalWebDriver}" />
+ <jvmarg value="-Dcom.vaadin.testbench.max.retries=${com.vaadin.testbench.max.retries}" />
+ <jvmarg value="-Dcom.vaadin.testbench.hub.url=${com.vaadin.testbench.hub.url}" />
+ <jvmarg value="-Dvaadin.testbench.developer.license=${vaadin.testbench.developer.license}" />
+ <test name="${junit.test.suite}" todir="${report.dir}" />
+ </junit>
+ </target>
+</project> \ No newline at end of file