diff options
243 files changed, 4984 insertions, 2709 deletions
diff --git a/WebContent/VAADIN/themes/valo/util/bourbon/functions/_transition-property-name.scss b/WebContent/VAADIN/themes/valo/util/bourbon/functions/_transition-property-name.scss index 111deeb70f..6ceae72102 100644 --- a/WebContent/VAADIN/themes/valo/util/bourbon/functions/_transition-property-name.scss +++ b/WebContent/VAADIN/themes/valo/util/bourbon/functions/_transition-property-name.scss @@ -14,7 +14,7 @@ @function transition-property-name($prop, $vendor: false) { // put other properties that need to be prefixed here aswell @if $vendor and $prop == transform { - @return unquote('-'+$vendor+'-'+$prop); + @return unquote('-' + $vendor + '-' + $prop); } @else { @return $prop; diff --git a/WebContent/VAADIN/themes/valo/util/readme.txt b/WebContent/VAADIN/themes/valo/util/readme.txt new file mode 100644 index 0000000000..6da898220f --- /dev/null +++ b/WebContent/VAADIN/themes/valo/util/readme.txt @@ -0,0 +1,8 @@ +The Bourbon library has been modified to work around the limitations of the Sass Compiler. +The following changes should be taken into account if Bourbon is upgraded to a newer +version: + +file _transition-property-name.scss, function transition-property-name: added space around +the operation '+'. This changed one line from +@return unquote('-'+$vendor+'-'+$prop); +to @return unquote('-' + $vendor + '-' + $prop);
\ No newline at end of file diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index ef60364202..c1102f4682 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -87,9 +87,9 @@ </servlet> <servlet> - <!-- This servlet is a separate instance for the sole purpose of - testing #12446 (com.vaadin.tests.components.ui.TimeoutRedirectResetsOnActivity) - because it modifies the VaadinService timeout parameters --> + <!-- This servlet is a separate instance for the sole purpose of testing + #12446 (com.vaadin.tests.components.ui.TimeoutRedirectResetsOnActivity) because + it modifies the VaadinService timeout parameters --> <servlet-name>VaadinApplicationRunnerWithTimeoutRedirect</servlet-name> <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class> </servlet> @@ -115,6 +115,17 @@ <async-supported>true</async-supported> </servlet> + <!-- For testing custom push path with, for example, Weblogic 12.1.2 --> + <servlet> + <servlet-name>VaadinApplicationRunnerWithPushPathTest</servlet-name> + <servlet-class>com.vaadin.launcher.ApplicationRunnerServlet</servlet-class> + <init-param> + <param-name>pushPath</param-name> + <param-value>ws</param-value> + </init-param> + <async-supported>true</async-supported> + </servlet> + <servlet-mapping> <servlet-name>Embed App 1</servlet-name> <url-pattern>/embed1/*</url-pattern> @@ -149,6 +160,11 @@ </servlet-mapping> <servlet-mapping> + <servlet-name>VaadinApplicationRunnerWithPushPathTest</servlet-name> + <url-pattern>/run-pushpath/*</url-pattern> + </servlet-mapping> + + <servlet-mapping> <servlet-name>IntegrationTest</servlet-name> <url-pattern>/integration/*</url-pattern> </servlet-mapping> diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 6cedeb1e21..efae20187e 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -41,26 +41,23 @@ <ul> <li><a href="#overview">Overview of Vaadin @version@ Release</a></li> - <li><a href="#changelog">Change log for Vaadin + <li><a href="#changelog">Change Log for Vaadin @version@</a></li> <li><a href="#enhancements">Enhancements in Vaadin @version-minor@</a></li> - <li><a href="#incompatible">Incompatible or behavior-altering changes in - @version-minor@</a></li> - <li><a href="#knownissues">Known issues in - @version-minor@</a></li> - <li><a href="#limitations">Limitations in + <li><a href="#incompatible">Incompatible or Behavior-altering Changes in @version-minor@</a></li> + <li><a href="#knownissues">Known Issues</a></li> + <li><a href="#limitations">Limitations</a></li> <li><a href="#vaadin">Vaadin Installation</a></li> <li><a href="#package">Package Contents</a></li> - <li><a href="#migrating">Migrating from Vaadin 6 to - Vaadin 7</a></li> + <li><a href="#migrating">Migrating from Vaadin 6</a></li> <li><a href="#dependencies">Vaadin @version@ dependencies</a></li> <li><a href="#upgrading">Upgrading to Vaadin @version-minor@</a></li> <li><a href="#supportedversions">Supported - technologies</a></li> + Technologies</a></li> <li><a href="#vaadinontheweb">Vaadin on the Web</a></li> </ul> @@ -74,7 +71,7 @@ </p> <!-- ================================================================ --> - <h3 id="changelog">Change log for Vaadin @version@</h3> + <h3 id="changelog">Change Log for Vaadin @version@</h3> <p>This release includes the following closed issues:</p> @@ -127,7 +124,7 @@ Notes for Vaadin 7.3.0</a>. </p> - <h3 id="incompatible">Incompatible or behavior-altering changes in @version-minor@</h3> + <h3 id="incompatible">Incompatible or Behavior-altering Changes in @version-minor@</h3> <ul> <li> <p>The org.json and com.google.gwt.json libraries have been replaced by elemental.json.</p> @@ -140,7 +137,7 @@ <li>Window's accessibility shortcut was moved to server-side. Now setCloseShortcut overrides the default value, while addCloseShortcut can be used to add more than one shortcut key for closing the window. The protected value closeShortcut in Window was removed.</li> </ul> - <h3 id="knownissues">Known issues</h3> + <h3 id="knownissues">Known Issues</h3> <ul> <li>Drag'n'drop in a Table doesn't work on touch devices running Internet Explorer (Windows Phone, Surface) @@ -332,7 +329,7 @@ directory of the web application that uses validation. </p> - <h2 id="upgrading">Upgrading from Vaadin 7.1 to Vaadin @version-minor@</h2> + <h2 id="upgrading">Upgrading to Vaadin @version-minor@</h2> <p>When upgrading from an earlier Vaadin version, you must: </p> @@ -514,12 +511,12 @@ </p> <ul> - <li>Mozilla Firefox 18-34</li> + <li>Mozilla Firefox 18-35</li> <li>Mozilla Firefox 17 ESR, 24 ESR, 31 ESR</li> <li>Internet Explorer 8-11</li> <li>Safari 6-8</li> <li>Opera 16-27</li> - <li>Google Chrome 23-39</li> + <li>Google Chrome 23-40</li> </ul> <p> diff --git a/build.properties b/build.properties index 53196da206..6845cda3e0 100644 --- a/build.properties +++ b/build.properties @@ -6,5 +6,5 @@ vaadin.url=http://vaadin.com vaadin.java.version=1.6 vaadin.version=0.0.0.unversioned-development-build vaadin.sass.version=0.9.12 -gwt.version=2.7.0.vaadin1 +gwt.version=2.7.0.vaadin2 commons-io.version=2.4 diff --git a/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java b/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java index 0d8f117329..d4ad3f838c 100644 --- a/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java +++ b/buildhelpers/src/com/vaadin/buildhelpers/GeneratePackageExports.java @@ -47,7 +47,8 @@ public class GeneratePackageExports { System.err .println("Invalid number of parameters\n" + "Usage: java -cp .. GenerateManifest <package.jar> <accepted package prefixes>\n" - + "Use -Dvaadin.version to specify the version to be used for the packages"); + + "Use -Dvaadin.version to specify the version to be used for the packages\n" + + "Use -DincludeNumberPackages=1 to include package names which start with a number (not 100% OSGi compatible)"); System.exit(1); } @@ -67,8 +68,14 @@ public class GeneratePackageExports { acceptedPackagePrefixes.add(args[i]); } + boolean includeNumberPackages = false; + if ("1".equals(System.getProperty("includeNumberPackages"))) { + includeNumberPackages = true; + } + // List the included Java packages - HashSet<String> packages = getPackages(jar, acceptedPackagePrefixes); + HashSet<String> packages = getPackages(jar, acceptedPackagePrefixes, + includeNumberPackages); // Avoid writing empty Export-Package attribute if (packages.isEmpty()) { @@ -171,7 +178,7 @@ public class GeneratePackageExports { } private static HashSet<String> getPackages(JarFile jar, - List<String> acceptedPackagePrefixes) { + List<String> acceptedPackagePrefixes, boolean includeNumberPackages) { HashSet<String> packages = new HashSet<String>(); Pattern startsWithNumber = Pattern.compile("\\.\\d"); @@ -194,7 +201,7 @@ public class GeneratePackageExports { String pkg = entry.getName().substring(0, lastSlash) .replace('/', '.'); - if (startsWithNumber.matcher(pkg).find()) { + if (!includeNumberPackages && startsWithNumber.matcher(pkg).find()) { continue; } diff --git a/client-compiled/build.xml b/client-compiled/build.xml index fb4f26bc73..5eb8decd22 100644 --- a/client-compiled/build.xml +++ b/client-compiled/build.xml @@ -124,6 +124,7 @@ <target name="jar" depends="default-widgetset"> <antcall target="common.jar"> <param name="osgi.extra.package.prefixes" value="VAADIN/widgetsets/" /> + <param name="osgi.includeNumberPackages" value="1" /> <reference torefid="extra.jar.includes" refid="jar.includes" /> </antcall> </target> diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java index 87fde2de32..f88a3b6f63 100644 --- a/client/src/com/vaadin/client/ApplicationConnection.java +++ b/client/src/com/vaadin/client/ApplicationConnection.java @@ -899,13 +899,11 @@ public class ApplicationConnection implements HasHandlers { RequestCallback requestCallback = new RequestCallback() { @Override public void onError(Request request, Throwable exception) { - handleCommunicationError(exception.getMessage(), -1); + handleError(exception.getMessage(), -1); } - private void handleCommunicationError(String details, int statusCode) { - if (!handleErrorInDelegate(details, statusCode)) { - showCommunicationError(details, statusCode); - } + private void handleError(String details, int statusCode) { + handleCommunicationError(details, statusCode); endRequest(); // Consider application not running any more and prevent all @@ -949,7 +947,7 @@ public class ApplicationConnection implements HasHandlers { } }).schedule(100); } else { - handleCommunicationError( + handleError( "Invalid status code 0 (server down?)", statusCode); } @@ -995,7 +993,7 @@ public class ApplicationConnection implements HasHandlers { } else if ((statusCode / 100) == 5) { // Something's wrong on the server, there's nothing the // client can do except maybe try again. - handleCommunicationError("Server error. Error code: " + handleError("Server error. Error code: " + statusCode, statusCode); return; } @@ -1062,8 +1060,17 @@ public class ApplicationConnection implements HasHandlers { if (isApplicationRunning()) { handleReceivedJSONMessage(start, jsonText, json); } else { - setApplicationRunning(true); - handleWhenCSSLoaded(jsonText, json); + if (!cssLoaded) { + // Application is starting up for the first time + setApplicationRunning(true); + handleWhenCSSLoaded(jsonText, json); + } else { + getLogger() + .warning( + "Ignored received message because application has already been stopped"); + return; + + } } } @@ -1498,7 +1505,9 @@ public class ApplicationConnection implements HasHandlers { VConsole.log("Postponing UIDL handling due to lock..."); pendingUIDLMessages.add(new PendingUIDLMessage(start, jsonText, json)); - forceHandleMessage.schedule(MAX_SUSPENDED_TIMEOUT); + if (!forceHandleMessage.isRunning()) { + forceHandleMessage.schedule(MAX_SUSPENDED_TIMEOUT); + } return; } @@ -3561,11 +3570,17 @@ public class ApplicationConnection implements HasHandlers { } } - private boolean handleErrorInDelegate(String details, int statusCode) { - if (communicationErrorDelegate == null) { - return false; + private void handleCommunicationError(String details, int statusCode) { + boolean handled = false; + if (communicationErrorDelegate != null) { + handled = communicationErrorDelegate.onError(details, statusCode); + } - return communicationErrorDelegate.onError(details, statusCode); + + if (!handled) { + showCommunicationError(details, statusCode); + } + } /** @@ -3640,7 +3655,7 @@ public class ApplicationConnection implements HasHandlers { push.init(this, pushState, new CommunicationErrorHandler() { @Override public boolean onError(String details, int statusCode) { - showCommunicationError(details, statusCode); + handleCommunicationError(details,statusCode); return true; } }); diff --git a/client/src/com/vaadin/client/LayoutManager.java b/client/src/com/vaadin/client/LayoutManager.java index 9775c29ab6..f77b61a5a3 100644 --- a/client/src/com/vaadin/client/LayoutManager.java +++ b/client/src/com/vaadin/client/LayoutManager.java @@ -189,8 +189,7 @@ public class LayoutManager { return element.vMeasuredSize || defaultSize; }-*/; - private final MeasuredSize getMeasuredSize(ComponentConnector connector) { - Element element = connector.getWidget().getElement(); + private final MeasuredSize getMeasuredSize(Element element) { MeasuredSize measuredSize = getMeasuredSize(element, null); if (measuredSize == null) { measuredSize = new MeasuredSize(); @@ -736,7 +735,7 @@ public class LayoutManager { private void measureConnector(ComponentConnector connector) { Profiler.enter("LayoutManager.measureConnector"); Element element = connector.getWidget().getElement(); - MeasuredSize measuredSize = getMeasuredSize(connector); + MeasuredSize measuredSize = getMeasuredSize(element); MeasureResult measureResult = measuredAndUpdate(element, measuredSize); if (measureResult.isChanged()) { @@ -1442,14 +1441,14 @@ public class LayoutManager { * of the component in pixels */ public void reportOuterHeight(ComponentConnector component, int outerHeight) { - MeasuredSize measuredSize = getMeasuredSize(component); + Element element = component.getWidget().getElement(); + MeasuredSize measuredSize = getMeasuredSize(element); if (isLayoutRunning()) { boolean heightChanged = measuredSize.setOuterHeight(outerHeight); if (heightChanged) { onConnectorChange(component, false, true); - notifyListenersAndDepdendents(component.getWidget() - .getElement(), false, true); + notifyListenersAndDepdendents(element, false, true); } currentDependencyTree.setNeedsVerticalMeasure(component, false); } else if (measuredSize.getOuterHeight() != outerHeight) { @@ -1523,14 +1522,14 @@ public class LayoutManager { * of the component in pixels */ public void reportOuterWidth(ComponentConnector component, int outerWidth) { - MeasuredSize measuredSize = getMeasuredSize(component); + Element element = component.getWidget().getElement(); + MeasuredSize measuredSize = getMeasuredSize(element); if (isLayoutRunning()) { boolean widthChanged = measuredSize.setOuterWidth(outerWidth); if (widthChanged) { onConnectorChange(component, true, false); - notifyListenersAndDepdendents(component.getWidget() - .getElement(), true, false); + notifyListenersAndDepdendents(element, true, false); } currentDependencyTree.setNeedsHorizontalMeasure(component, false); } else if (measuredSize.getOuterWidth() != outerWidth) { diff --git a/client/src/com/vaadin/client/Util.java b/client/src/com/vaadin/client/Util.java index 778f7c3861..99e6507d81 100644 --- a/client/src/com/vaadin/client/Util.java +++ b/client/src/com/vaadin/client/Util.java @@ -825,30 +825,29 @@ public class Util { * @return true if the collections contain the same elements in the same * order, false otherwise */ - public static boolean collectionsEquals(Collection collection1, - Collection collection2) { + public static boolean collectionsEquals(Collection<?> collection1, + Collection<?> collection2) { if (collection1 == null) { return collection2 == null; } if (collection2 == null) { return false; } - Iterator<Object> collection1Iterator = collection1.iterator(); - Iterator<Object> collection2Iterator = collection2.iterator(); + + if (collection1.size() != collection2.size()) { + return false; + } + + Iterator<?> collection1Iterator = collection1.iterator(); + Iterator<?> collection2Iterator = collection2.iterator(); while (collection1Iterator.hasNext()) { - if (!collection2Iterator.hasNext()) { - return false; - } Object collection1Object = collection1Iterator.next(); Object collection2Object = collection2Iterator.next(); if (collection1Object != collection2Object) { return false; } } - if (collection2Iterator.hasNext()) { - return false; - } return true; } diff --git a/client/src/com/vaadin/client/VTooltip.java b/client/src/com/vaadin/client/VTooltip.java index 453563370c..a9406935dc 100644 --- a/client/src/com/vaadin/client/VTooltip.java +++ b/client/src/com/vaadin/client/VTooltip.java @@ -20,17 +20,7 @@ import com.google.gwt.aria.client.RelevantValue; import com.google.gwt.aria.client.Roles; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Display; -import com.google.gwt.event.dom.client.BlurEvent; -import com.google.gwt.event.dom.client.BlurHandler; -import com.google.gwt.event.dom.client.DomEvent; -import com.google.gwt.event.dom.client.FocusEvent; -import com.google.gwt.event.dom.client.FocusHandler; -import com.google.gwt.event.dom.client.KeyDownEvent; -import com.google.gwt.event.dom.client.KeyDownHandler; -import com.google.gwt.event.dom.client.MouseDownEvent; -import com.google.gwt.event.dom.client.MouseDownHandler; -import com.google.gwt.event.dom.client.MouseMoveEvent; -import com.google.gwt.event.dom.client.MouseMoveHandler; +import com.google.gwt.event.dom.client.*; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; @@ -388,7 +378,8 @@ public class VTooltip extends VOverlay { } private class TooltipEventHandler implements MouseMoveHandler, - KeyDownHandler, FocusHandler, BlurHandler, MouseDownHandler { + KeyDownHandler, FocusHandler, BlurHandler, MouseDownHandler, + MouseUpHandler, TouchStartHandler { /** * Current element hovered @@ -401,6 +392,11 @@ public class VTooltip extends VOverlay { private boolean handledByFocus; /** + * Indicates whether the tooltip is being called after a touch event. + */ + private boolean touchInitiated = false; + + /** * Locate the tooltip for given element * * @param element @@ -450,7 +446,19 @@ public class VTooltip extends VOverlay { @Override public void onMouseMove(MouseMoveEvent mme) { - handleShowHide(mme, false); + if (!touchInitiated) { + handleShowHide(mme, false); + } + } + + @Override + public void onMouseUp(MouseUpEvent event) { + touchInitiated = false; + } + + @Override + public void onTouchStart(TouchStartEvent te) { + touchInitiated = true; } @Override @@ -550,9 +558,11 @@ public class VTooltip extends VOverlay { Profiler.enter("VTooltip.connectHandlersToWidget"); widget.addDomHandler(tooltipEventHandler, MouseMoveEvent.getType()); widget.addDomHandler(tooltipEventHandler, MouseDownEvent.getType()); + widget.addDomHandler(tooltipEventHandler, MouseUpEvent.getType()); widget.addDomHandler(tooltipEventHandler, KeyDownEvent.getType()); widget.addDomHandler(tooltipEventHandler, FocusEvent.getType()); widget.addDomHandler(tooltipEventHandler, BlurEvent.getType()); + widget.addDomHandler(tooltipEventHandler, TouchStartEvent.getType()); Profiler.leave("VTooltip.connectHandlersToWidget"); } diff --git a/client/src/com/vaadin/client/WidgetUtil.java b/client/src/com/vaadin/client/WidgetUtil.java index 4c991b2c3d..5f88f6da46 100644 --- a/client/src/com/vaadin/client/WidgetUtil.java +++ b/client/src/com/vaadin/client/WidgetUtil.java @@ -439,7 +439,13 @@ public class WidgetUtil { if (BrowserInfo.get().requiresOverflowAutoFix()) { final String originalOverflow = elem.getStyle().getProperty( "overflow"); - if ("hidden".equals(originalOverflow)) { + 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; } @@ -453,6 +459,14 @@ public class WidgetUtil { 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; diff --git a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java index da08928f36..787da9bc6f 100644 --- a/client/src/com/vaadin/client/communication/AtmospherePushConnection.java +++ b/client/src/com/vaadin/client/communication/AtmospherePushConnection.java @@ -24,6 +24,8 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window.Location; import com.vaadin.client.ApplicationConfiguration; import com.vaadin.client.ApplicationConnection; +import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent; +import com.vaadin.client.ApplicationConnection.ApplicationStoppedHandler; import com.vaadin.client.ApplicationConnection.CommunicationErrorHandler; import com.vaadin.client.ResourceLoader; import com.vaadin.client.ResourceLoader.ResourceLoadEvent; @@ -41,7 +43,7 @@ import elemental.json.JsonObject; /** * The default {@link PushConnection} implementation that uses Atmosphere for * handling the communication channel. - * + * * @author Vaadin Ltd * @since 7.1 */ @@ -133,6 +135,8 @@ public class AtmospherePushConnection implements PushConnection { */ private Command pendingDisconnectCommand; + private String pushPath; + public AtmospherePushConnection() { } @@ -150,6 +154,25 @@ public class AtmospherePushConnection implements PushConnection { this.connection = connection; this.errorHandler = errorHandler; + connection.addHandler(ApplicationStoppedEvent.TYPE, + new ApplicationStoppedHandler() { + + @Override + public void onApplicationStopped( + ApplicationStoppedEvent event) { + if (state == State.DISCONNECT_PENDING + || state == State.DISCONNECTED) { + return; + } + + disconnect(new Command() { + @Override + public void execute() { + } + }); + + } + }); config = createConfig(); String debugParameter = Location.getParameter("debug"); if ("push".equals(debugParameter)) { @@ -160,6 +183,9 @@ public class AtmospherePushConnection implements PushConnection { pushConfiguration.parameters.get(param)); } + pushPath = pushConfiguration.pushPath; + assert pushPath != null; + runWhenAtmosphereLoaded(new Command() { @Override public void execute() { @@ -176,7 +202,7 @@ public class AtmospherePushConnection implements PushConnection { private void connect() { String baseUrl = connection .translateVaadinUri(ApplicationConstants.APP_PROTOCOL_PREFIX - + ApplicationConstants.PUSH_PATH + '/'); + + pushPath + '/'); String extraParams = UIConstants.UI_ID_PARAMETER + "=" + connection.getConfiguration().getUIId(); @@ -251,9 +277,9 @@ public class AtmospherePushConnection implements PushConnection { /** * Called whenever a server push connection is established (or * re-established). - * + * * @param response - * + * * @since 7.2 */ protected void onConnect(AtmosphereResponse response) { @@ -319,14 +345,6 @@ public class AtmospherePushConnection implements PushConnection { message = message.substring(9, message.length() - 1); connection.handlePushMessage(message); } - - if (!connection.isApplicationRunning()) { - disconnect(new Command() { - @Override - public void execute() { - } - }); - } } /** @@ -342,7 +360,7 @@ public class AtmospherePushConnection implements PushConnection { /** * Called if the push connection fails. Atmosphere will automatically retry * the connection until successful. - * + * */ protected void onError(AtmosphereResponse response) { state = State.DISCONNECTED; diff --git a/client/src/com/vaadin/client/connectors/GridConnector.java b/client/src/com/vaadin/client/connectors/GridConnector.java index 71450f6146..495bcd0411 100644 --- a/client/src/com/vaadin/client/connectors/GridConnector.java +++ b/client/src/com/vaadin/client/connectors/GridConnector.java @@ -485,6 +485,11 @@ public class GridConnector extends AbstractHasComponentsConnector implements } }); } + + @Override + public void recalculateColumnWidths() { + getWidget().recalculateColumnWidths(); + } }); getWidget().addSelectionHandler(internalSelectionChangeHandler); diff --git a/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java b/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java index bd676e4ee9..1de271c646 100644 --- a/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java +++ b/client/src/com/vaadin/client/data/AbstractRemoteDataSource.java @@ -541,7 +541,7 @@ public abstract class AbstractRemoteDataSource<T> implements DataSource<T> { Range oldCached = cached; cached = cached.offsetBy(count); - for (int i = 1; i <= indexToRowMap.size(); i++) { + for (int i = 1; i <= cached.length(); i++) { int oldIndex = oldCached.getEnd() - i; int newIndex = cached.getEnd() - i; moveRowFromIndexToIndex(oldIndex, newIndex); diff --git a/client/src/com/vaadin/client/renderers/ComplexRenderer.java b/client/src/com/vaadin/client/renderers/ComplexRenderer.java index 75ea523cdc..262de79468 100644 --- a/client/src/com/vaadin/client/renderers/ComplexRenderer.java +++ b/client/src/com/vaadin/client/renderers/ComplexRenderer.java @@ -29,8 +29,8 @@ import com.vaadin.client.widget.grid.RendererCellReference; /** * Base class for renderers that needs initialization and destruction logic - * (override {@link #init(FlyweightCell) and #destroy(FlyweightCell) } and event - * handling (see {@link #onBrowserEvent(Cell, NativeEvent)}, + * (override {@link #init(FlyweightCell)} and {@link #destroy(FlyweightCell) } + * and event handling (see {@link #onBrowserEvent(Cell, NativeEvent)}, * {@link #getConsumedEvents()} and {@link #onActivate()}. * * <p> @@ -48,7 +48,7 @@ public abstract class ComplexRenderer<T> implements Renderer<T> { * * @param cell * The cell. Note that the cell is not to be stored outside of - * the method as the cell install will change. See + * the method as the cell instance will change. See * {@link FlyweightCell} */ public abstract void init(RendererCellReference cell); @@ -62,7 +62,7 @@ public abstract class ComplexRenderer<T> implements Renderer<T> { * * @param cell * The cell. Note that the cell is not to be stored outside of - * the method as the cell install will change. See + * the method as the cell instance will change. See * {@link FlyweightCell} */ public void destroy(RendererCellReference cell) { diff --git a/client/src/com/vaadin/client/ui/VFilterSelect.java b/client/src/com/vaadin/client/ui/VFilterSelect.java index c0575b1ea5..c99ed49c91 100644 --- a/client/src/com/vaadin/client/ui/VFilterSelect.java +++ b/client/src/com/vaadin/client/ui/VFilterSelect.java @@ -813,6 +813,7 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, clearItems(); final Iterator<FilterSelectSuggestion> it = suggestions.iterator(); + boolean isFirstIteration = true; while (it.hasNext()) { final FilterSelectSuggestion s = it.next(); final MenuItem mi = new MenuItem(s.getDisplayString(), true, s); @@ -821,9 +822,21 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, WidgetUtil.sinkOnloadForImages(mi.getElement()); this.addItem(mi); - if (s == currentSuggestion) { + + // By default, first item on the list is always highlighted, + // unless adding new items is allowed. + if (isFirstIteration && !allowNewItem) { + selectItem(mi); + } + + // If the filter matches the current selection, highlight that + // instead of the first item. + if (tb.getText().equals(s.getReplacementString()) + && s == currentSuggestion) { selectItem(mi); } + + isFirstIteration = false; } } @@ -1178,8 +1191,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, /** For internal use only. May be removed or replaced in the future. */ public boolean updateSelectionWhenReponseIsReceived = false; - private boolean tabPressedWhenPopupOpen = false; - /** For internal use only. May be removed or replaced in the future. */ public boolean initDone = false; @@ -1421,8 +1432,10 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, return; } if (!filter.equals(lastFilter)) { - // we are on subsequent page and text has changed -> reset page - if ("".equals(filter)) { + // when filtering, let the server decide the page unless we've + // set the filter to empty and explicitly said that we want to see + // the results starting from page 0. + if ("".equals(filter) && page != 0) { // let server decide page = -1; } else { @@ -1437,7 +1450,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, lastFilter = filter; currentPage = page; - } /** For internal use only. May be removed or replaced in the future. */ @@ -1768,16 +1780,12 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, selectPrevPage(); event.stopPropagation(); break; - case KeyCodes.KEY_TAB: - tabPressedWhenPopupOpen = true; - filterOptions(currentPage); - // onBlur() takes care of the rest - break; case KeyCodes.KEY_ESCAPE: reset(); DOM.eventPreventDefault(DOM.eventGetCurrentEvent()); event.stopPropagation(); break; + case KeyCodes.KEY_TAB: case KeyCodes.KEY_ENTER: if (suggestionPopup.menu.getKeyboardSelectedItem() == null) { /* @@ -1785,17 +1793,8 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, * text (causes popup to open) and then pressing enter. */ if (!allowNewItem) { - /* - * New items are not allowed: If there is only one - * suggestion, select that. If there is more than one - * suggestion Enter key should work as Escape key. Otherwise - * do nothing. - */ - if (currentSuggestions.size() == 1) { - onSuggestionSelected(currentSuggestions.get(0)); - } else if (currentSuggestions.size() > 1) { - reset(); - } + onSuggestionSelected(currentSuggestions + .get(suggestionPopup.menu.getSelectedIndex())); } else { // Handle addition of new items. suggestionPopup.menu.doSelectedItemAction(); @@ -1863,7 +1862,9 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, break; default: if (textInputEnabled) { - filterOptions(currentPage); + // when filtering, we always want to see the results on the + // first page first. + filterOptions(0); } break; } @@ -2069,19 +2070,6 @@ public class VFilterSelect extends Composite implements Field, KeyDownHandler, focused = false; if (!readonly) { - // much of the TAB handling takes place here - if (tabPressedWhenPopupOpen) { - tabPressedWhenPopupOpen = false; - waitingForFilteringResponse = false; - suggestionPopup.menu.doSelectedItemAction(); - suggestionPopup.hide(); - } else if ((!suggestionPopup.isAttached() && waitingForFilteringResponse) - || suggestionPopup.isJustClosed()) { - // typing so fast the popup was never opened, or it's just - // closed - waitingForFilteringResponse = false; - suggestionPopup.menu.doSelectedItemAction(); - } if (selectedOptionKey == null) { setPromptingOn(); } else if (currentSuggestion != null) { diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 6b4bb8eb9d..12de2724fc 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -1225,7 +1225,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(); @@ -3380,7 +3385,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /** * Saves natural column width if it hasn't been saved already. - * + * * @param columnIndex * @since 7.3.9 */ @@ -3612,9 +3617,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); } @@ -4322,7 +4327,7 @@ public class VScrollTable extends FlowPanel implements HasWidgets, /** * Saves natural column width if it hasn't been saved already. - * + * * @param columnIndex * @since 7.3.9 */ diff --git a/client/src/com/vaadin/client/ui/VTextualDate.java b/client/src/com/vaadin/client/ui/VTextualDate.java index b95f696030..9055609e69 100644 --- a/client/src/com/vaadin/client/ui/VTextualDate.java +++ b/client/src/com/vaadin/client/ui/VTextualDate.java @@ -25,7 +25,11 @@ import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.event.dom.client.KeyCodes; +import com.google.gwt.event.dom.client.KeyDownEvent; +import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.user.client.ui.TextBox; +import com.vaadin.client.BrowserInfo; import com.vaadin.client.Focusable; import com.vaadin.client.LocaleNotLoadedException; import com.vaadin.client.LocaleService; @@ -39,7 +43,7 @@ import com.vaadin.shared.ui.datefield.Resolution; public class VTextualDate extends VDateField implements Field, ChangeHandler, Focusable, SubPartAware, HandlesAriaCaption, HandlesAriaInvalid, - HandlesAriaRequired { + HandlesAriaRequired, KeyDownHandler { private static final String PARSE_ERROR_CLASSNAME = "-parseerror"; @@ -107,7 +111,9 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, VTextualDate.this.fireEvent(event); } }); - + if (BrowserInfo.get().isIE()) { + addDomHandler(this, KeyDownEvent.getType()); + } add(text); } @@ -386,4 +392,14 @@ public class VTextualDate extends VDateField implements Field, ChangeHandler, return null; } + + @Override + public void onKeyDown(KeyDownEvent event) { + if (BrowserInfo.get().isIE() + && event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { + // IE does not send change events when pressing enter in a text + // input so we handle it using a key listener instead + onChange(null); + } + } } diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index 461181e18a..8757f46e71 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -166,7 +166,12 @@ public class ComboBoxConnector extends AbstractFieldConnector implements ) { String[] selectedKeys = uidl.getStringArrayVariable("selected"); - if (selectedKeys.length > 0) { + + // when filtering with empty filter, server sets the selected key + // to "", which we don't select here. Otherwise we won't be able to + // reset back to the item that was selected before filtering + // started. + if (selectedKeys.length > 0 && !selectedKeys[0].equals("")) { performSelection(selectedKeys[0]); } else { resetSelection(); diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java index b97cf73989..616667c367 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java @@ -22,9 +22,12 @@ import com.google.gwt.aria.client.Roles; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; -import com.google.gwt.user.client.DOM; -import com.google.gwt.user.client.Event; -import com.google.gwt.user.client.Timer; +import com.google.gwt.event.dom.client.BlurEvent; +import com.google.gwt.event.dom.client.BlurHandler; +import com.google.gwt.event.dom.client.FocusEvent; +import com.google.gwt.event.dom.client.FocusHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.*; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; @@ -44,6 +47,7 @@ import com.vaadin.shared.ui.AlignmentInfo; public final class Slot extends SimplePanel { private static final String ALIGN_CLASS_PREFIX = "v-align-"; + private static final int TOUCH_ERROR_MESSAGE_HIDE_DELAY = 200; private final VAbstractOrderedLayout layout; @@ -55,8 +59,13 @@ public final class Slot extends SimplePanel { private Element captionText; private Icon icon; private Element errorIcon; + private Element errorMessage; private Element requiredIcon; + private HandlerRegistration focusRegistration; + private HandlerRegistration blurRegistration; + private boolean labelClicked = false; + private ElementResizeListener captionResizeListener; private ElementResizeListener widgetResizeListener; @@ -582,9 +591,21 @@ public final class Slot extends SimplePanel { errorIcon.setClassName("v-errorindicator"); } caption.appendChild(errorIcon); - } else if (errorIcon != null) { - errorIcon.removeFromParent(); - errorIcon = null; + + if(BrowserInfo.get().isTouchDevice()) { + addFocusHandlerToWidget(error, widget); + addBlurHandlerToWidget(widget); + } + + } else { + if (errorIcon != null) { + errorIcon.removeFromParent(); + errorIcon = null; + } + + if (errorMessage != null) { + removeErrorMessageAndHandlers(); + } } if (caption != null) { @@ -651,6 +672,81 @@ public final class Slot extends SimplePanel { } } + private void removeErrorMessageAndHandlers() { + errorMessage.removeFromParent(); + errorMessage = null; + + if (focusRegistration != null) { + focusRegistration.removeHandler(); + focusRegistration = null; + } + + if(blurRegistration != null) { + blurRegistration.removeHandler(); + blurRegistration = null; + } + } + + private void addFocusHandlerToWidget(final String error, Widget widget) { + focusRegistration = widget.addHandler(new FocusHandler() { + @Override + public void onFocus(FocusEvent event) { + if(labelClicked) { + labelClicked = false; + return; + } + if (errorMessage == null) { + errorMessage = DOM.createDiv(); + errorMessage.setClassName("v-touch-error-message"); + } + errorMessage.setInnerHTML(error); + captionWrap.appendChild(errorMessage); + } + }, FocusEvent.getType()); + } + + private void addBlurHandlerToWidget(final Widget widget) { + blurRegistration = widget.addHandler(new BlurHandler() { + @Override + public void onBlur(BlurEvent event) { + if(errorMessage != null) { + addClickHandlerToErrorMessage(widget); + } + scheduleErrorMessageHide(TOUCH_ERROR_MESSAGE_HIDE_DELAY); + } + }, BlurEvent.getType()); + } + + private void scheduleErrorMessageHide(int delay) { + //Delaying hiding to allow error message click handler + //do his job and return the focus back if error message was tapped + Timer hideTimer = new Timer() { + @Override + public void run() { + if(errorMessage != null) { + errorMessage.removeFromParent(); + errorMessage = null; + } + } + }; + hideTimer.schedule(delay); + } + + private void addClickHandlerToErrorMessage(final Widget widget) { + Event.sinkEvents(errorMessage, Event.ONCLICK); + Event.setEventListener(errorMessage, new EventListener() { + @Override + public void onBrowserEvent(Event event) { + if(Event.ONCLICK == event.getTypeInt()) { + errorMessage.removeFromParent(); + errorMessage = null; + labelClicked = true; + widget.getElement().focus(); + } + } + }); + } + /** * Does the slot have a caption */ diff --git a/client/src/com/vaadin/client/ui/window/WindowConnector.java b/client/src/com/vaadin/client/ui/window/WindowConnector.java index 5214c33eec..9b710981d8 100644 --- a/client/src/com/vaadin/client/ui/window/WindowConnector.java +++ b/client/src/com/vaadin/client/ui/window/WindowConnector.java @@ -405,6 +405,10 @@ public class WindowConnector extends AbstractSingleComponentContainerConnector // centered is this is unset on move/resize window.centered = state.centered; + // Ensure centering before setting visible (#16486) + if (window.centered && getState().windowMode != WindowMode.MAXIMIZED) { + window.center(); + } window.setVisible(true); // ensure window is not larger than browser window diff --git a/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java b/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java index 6e25e82235..8628adb05f 100644 --- a/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java +++ b/client/src/com/vaadin/client/widget/escalator/FlyweightRow.java @@ -21,7 +21,6 @@ import java.util.Iterator; import java.util.List; import com.google.gwt.dom.client.TableRowElement; -import com.vaadin.client.widgets.Escalator; /** * An internal implementation of the {@link Row} interface. diff --git a/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java b/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java index ef8713b82f..2b33d7103f 100644 --- a/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java +++ b/client/src/com/vaadin/client/widget/escalator/ScrollbarBundle.java @@ -22,6 +22,7 @@ import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.dom.client.Style.Overflow; import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.dom.client.Style.Visibility; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.event.shared.HandlerManager; @@ -103,18 +104,20 @@ public abstract class ScrollbarBundle implements DeferredWorker { VERTICAL, HORIZONTAL; } - private class TemporaryResizer extends Object { + private class TemporaryResizer { private static final int TEMPORARY_RESIZE_DELAY = 1000; private final Timer timer = new Timer() { @Override public void run() { internalSetScrollbarThickness(1); + root.getStyle().setVisibility(Visibility.HIDDEN); } }; public void show() { internalSetScrollbarThickness(OSX_INVISIBLE_SCROLLBAR_FAKE_SIZE_PX); + root.getStyle().setVisibility(Visibility.VISIBLE); timer.schedule(TEMPORARY_RESIZE_DELAY); } } @@ -332,7 +335,7 @@ public abstract class ScrollbarBundle implements DeferredWorker { private boolean isLocked = false; - /** @deprecarted access via {@link #getHandlerManager()} instead. */ + /** @deprecated access via {@link #getHandlerManager()} instead. */ @Deprecated private HandlerManager handlerManager; @@ -425,8 +428,6 @@ public abstract class ScrollbarBundle implements DeferredWorker { @Override public void onScroll(ScrollEvent event) { setOffsetSizeNow(px); - offsetSizeTemporaryScrollHandler.removeHandler(); - offsetSizeTemporaryScrollHandler = null; } }); setScrollPos(0); @@ -440,6 +441,10 @@ public abstract class ScrollbarBundle implements DeferredWorker { recalculateMaxScrollPos(); forceScrollbar(showsScrollHandle()); fireVisibilityChangeIfNeeded(); + if (offsetSizeTemporaryScrollHandler != null) { + offsetSizeTemporaryScrollHandler.removeHandler(); + offsetSizeTemporaryScrollHandler = null; + } } /** @@ -510,6 +515,17 @@ public abstract class ScrollbarBundle implements DeferredWorker { } /** + * Should be called whenever this bundle is attached to the DOM (typically, + * from the onLoad of the containing widget). Used to ensure the DOM scroll + * position is maintained when detaching and reattaching the bundle. + * + * @since 7.4.1 + */ + public void onLoad() { + internalSetScrollPos(toInt32(scrollPos)); + } + + /** * Truncates a double such that no decimal places are retained. * <p> * E.g. {@code trunc(2.3d) == 2.0d} and {@code trunc(-2.3d) == -2.0d}. @@ -606,8 +622,6 @@ public abstract class ScrollbarBundle implements DeferredWorker { @Override public void onScroll(ScrollEvent event) { setScrollSizeNow(px); - scrollSizeTemporaryScrollHandler.removeHandler(); - scrollSizeTemporaryScrollHandler = null; } }); setScrollPos(0); @@ -621,6 +635,10 @@ public abstract class ScrollbarBundle implements DeferredWorker { recalculateMaxScrollPos(); forceScrollbar(showsScrollHandle()); fireVisibilityChangeIfNeeded(); + if (scrollSizeTemporaryScrollHandler != null) { + scrollSizeTemporaryScrollHandler.removeHandler(); + scrollSizeTemporaryScrollHandler = null; + } } /** @@ -666,9 +684,11 @@ public abstract class ScrollbarBundle implements DeferredWorker { invisibleScrollbarTemporaryResizer.show(); } }); + root.getStyle().setVisibility(Visibility.HIDDEN); } else { Event.sinkEvents(root, 0); Event.setEventListener(root, null); + root.getStyle().clearVisibility(); } internalSetScrollbarThickness(Math.max(1d, px)); diff --git a/client/src/com/vaadin/client/widgets/Escalator.java b/client/src/com/vaadin/client/widgets/Escalator.java index c9a1efde98..5281a3f7d4 100644 --- a/client/src/com/vaadin/client/widgets/Escalator.java +++ b/client/src/com/vaadin/client/widgets/Escalator.java @@ -47,6 +47,7 @@ import com.google.gwt.dom.client.TableRowElement; import com.google.gwt.dom.client.TableSectionElement; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.logging.client.LogConfiguration; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.RequiresResize; @@ -334,7 +335,6 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker private double touches = 0; private int lastX = 0; private int lastY = 0; - private double lastTime = 0; private boolean snappedScrollEnabled = true; private double deltaX = 0; private double deltaY = 0; @@ -344,7 +344,10 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker private CustomTouchEvent latestTouchMoveEvent; /** The timestamp of {@link #flickPageX1} and {@link #flickPageY1} */ - private double flickTimestamp = Double.MIN_VALUE; + private double flickStartTime = 0; + + /** The timestamp of {@link #flickPageX2} and {@link #flickPageY2} */ + private double flickTimestamp = 0; /** The most recent flick touch reference Y */ private double flickPageY1 = -1; @@ -367,6 +370,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker * over here. */ private AnimationCallback mover = new AnimationCallback() { + @Override public void execute(double timestamp) { if (touches != 1) { @@ -377,17 +381,16 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker final int y = latestTouchMoveEvent.getPageY(); /* - * Check if we need a new flick coordinate sample (more than - * FLICK_POLL_FREQUENCY ms have passed since the last - * sample) + * Check if we need a new flick coordinate sample ( more + * than FLICK_POLL_FREQUENCY ms have passed since the last + * sample ) */ - if (timestamp - flickTimestamp > FLICK_POLL_FREQUENCY) { - flickTimestamp = timestamp; - flickPageY2 = flickPageY1; - flickPageY1 = y; + if (System.currentTimeMillis() - flickTimestamp > FLICK_POLL_FREQUENCY) { - flickPageX2 = flickPageX1; - flickPageX1 = x; + flickTimestamp = System.currentTimeMillis(); + // Set target coordinates + flickPageY2 = y; + flickPageX2 = x; } deltaX = x - lastX; @@ -395,12 +398,6 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker lastX = x; lastY = y; - /* - * Instead of using the provided arbitrary timestamp, let's - * use a known-format and reproducible timestamp. - */ - lastTime = Duration.currentTimeMillis(); - // snap the scroll to the major axes, at first. if (snappedScrollEnabled) { final double oldDeltaX = deltaX; @@ -476,6 +473,14 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker lastX = event.getPageX(); lastY = event.getPageY(); + // Reset flick parameters + flickPageX1 = lastX; + flickPageX2 = -1; + flickPageY1 = lastY; + flickPageY2 = -1; + flickStartTime = System.currentTimeMillis(); + flickTimestamp = 0; + snappedScrollEnabled = true; } @@ -513,25 +518,18 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker final double finalPageY; final double finalPageX; - double deltaT = lastTime - flickTimestamp; + double deltaT = flickTimestamp - flickStartTime; boolean onlyOneSample = flickPageX2 < 0 || flickPageY2 < 0; - if (onlyOneSample || deltaT > FLICK_POLL_FREQUENCY / 3) { - finalPageY = flickPageY1; - finalPageX = flickPageX1; + if (onlyOneSample) { + finalPageX = latestTouchMoveEvent.getPageX(); + finalPageY = latestTouchMoveEvent.getPageY(); } else { - deltaT += FLICK_POLL_FREQUENCY; finalPageY = flickPageY2; finalPageX = flickPageX2; } - flickPageY1 = -1; - flickPageY2 = -1; - flickTimestamp = Double.MIN_VALUE; - - double deltaX = latestTouchMoveEvent.getPageX() - - finalPageX; - double deltaY = latestTouchMoveEvent.getPageY() - - finalPageY; + double deltaX = finalPageX - flickPageX1; + double deltaY = finalPageY - flickPageY1; escalator.scroller .handleFlickScroll(deltaX, deltaY, deltaT); @@ -821,18 +819,23 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker double tableWrapperWidth = widthOfEscalator; boolean verticalScrollNeeded = scrollContentHeight > tableWrapperHeight - - header.heightOfSection - footer.heightOfSection; - boolean horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth; + + WidgetUtil.PIXEL_EPSILON + - header.heightOfSection + - footer.heightOfSection; + boolean horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth + + WidgetUtil.PIXEL_EPSILON; // One dimension got scrollbars, but not the other. Recheck time! if (verticalScrollNeeded != horizontalScrollNeeded) { if (!verticalScrollNeeded && horizontalScrollNeeded) { verticalScrollNeeded = scrollContentHeight > tableWrapperHeight + + WidgetUtil.PIXEL_EPSILON - header.heightOfSection - footer.heightOfSection - horizontalScrollbar.getScrollbarThickness(); } else { horizontalScrollNeeded = scrollContentWidth > tableWrapperWidth + + WidgetUtil.PIXEL_EPSILON - verticalScrollbar.getScrollbarThickness(); } } @@ -1812,12 +1815,13 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker */ protected void reapplyRowWidths() { double rowWidth = columnConfiguration.calculateRowWidth(); + if (rowWidth < 0) { + return; + } - com.google.gwt.dom.client.Element row = root.getFirstChildElement(); + Element row = root.getFirstChildElement(); while (row != null) { - if (rowWidth >= 0) { - row.getStyle().setWidth(rowWidth, Unit.PX); - } + row.getStyle().setWidth(rowWidth, Unit.PX); row = row.getNextSiblingElement(); } } @@ -2037,22 +2041,17 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker cellClone.getStyle().clearWidth(); rowElement.insertBefore(cellClone, cellOriginal); - - /* - * [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: not - * using the double-version is a workaround for a bug. It'll be - * converted to use the double version at a later time - */ double requiredWidth = WidgetUtil - .getRequiredWidthBoundingClientRect(cellClone); + .getRequiredWidthBoundingClientRectDouble(cellClone); - if (BrowserInfo.get().isIE9()) { + if (BrowserInfo.get().isIE()) { /* - * IE9 does not support subpixels. Usually it is rounded - * down which leads to content not shown. Increase the - * counted required size by one just to be on the safe side. + * IE browsers have some issues with subpixels. Occasionally + * content is overflown even if not necessary. Increase the + * counted required size by 0.01 just to be on the safe + * side. */ - requiredWidth += 1; + requiredWidth += 0.01; } maxCellWidth = Math.max(requiredWidth, maxCellWidth); @@ -3794,7 +3793,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } else { /* * the column's width is calculated at Escalator.onLoad - * via measureIfNeeded! + * via measureAndSetWidthIfNeeded! */ measuringRequested = true; } @@ -3820,7 +3819,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker * widths yet. * * This is fixed during Escalator.onLoad, by the call to - * "measureIfNeeded", which fixes "everything". + * "measureAndSetWidthIfNeeded", which fixes "everything". */ if (!measuringRequested) { return calculatedWidth; @@ -3835,7 +3834,7 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker * Called by {@link Escalator#onLoad()}. */ public boolean measureAndSetWidthIfNeeded() { - assert isAttached() : "Column.measureIfNeeded() was called even though Escalator was not attached!"; + assert isAttached() : "Column.measureAndSetWidthIfNeeded() was called even though Escalator was not attached!"; if (measuringRequested) { measuringRequested = false; @@ -3853,6 +3852,11 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker private final List<Column> columns = new ArrayList<Column>(); private int frozenColumns = 0; + /* + * TODO: this is a bit of a duplicate functionality with the + * Column.calculatedWidth caching. Probably should use one or the other, + * not both + */ /** * A cached array of all the calculated column widths. * @@ -3997,6 +4001,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker */ @Override public void insertColumns(final int index, final int numberOfColumns) { + subpixelBrowserBugDetector.invalidateFix(); + // Validate if (index < 0 || index > getColumnCount()) { throw new IndexOutOfBoundsException("The given index(" + index @@ -4148,14 +4154,23 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker for (Entry<Integer, Double> entry : indexWidthMap.entrySet()) { int index = entry.getKey().intValue(); double width = entry.getValue().doubleValue(); + + if (index == getColumnCount() - 1) { + subpixelBrowserBugDetector.invalidateFix(); + } + checkValidColumnIndex(index); columns.get(index).setWidth(width); + } widthsArray = null; header.reapplyColumnWidths(); body.reapplyColumnWidths(); footer.reapplyColumnWidths(); + + subpixelBrowserBugDetector.checkAndFix(); + recalculateElementSizes(); } @@ -4250,6 +4265,137 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } } + private class SubpixelBrowserBugDetector { + private static final double SUBPIXEL_ADJUSTMENT = .1; + private boolean hasAlreadyBeenFixed = false; + + /** + * This is a fix essentially for Firefox and how it handles subpixels. + * <p> + * Even if an element has {@code style="width: 1000.12px"}, the bounding + * box's width in Firefox is usually nothing of that sort. It's actually + * 1000.11669921875 (in version 35.0.1). That's not even close, when + * talking about floating point precision. Other browsers handle the + * subpixels way better + * <p> + * In any case, we need to fix that. And that's fixed by simply checking + * if the sum of the width of all the cells is larger than the width of + * the row. If it is, we <i>hack</i> the last column + * {@value #SUBPIXEL_ADJUSTMENT}px narrower. + */ + public void checkAndFix() { + if (!hasAlreadyBeenFixed && hasSubpixelBrowserBug()) { + fixSubpixelBrowserBug(); + hasAlreadyBeenFixed = true; + } + } + + public void invalidateFix() { + adjustBookkeepingPixels(SUBPIXEL_ADJUSTMENT); + hasAlreadyBeenFixed = false; + } + + private boolean hasSubpixelBrowserBug() { + final RowContainer rowContainer; + if (header.getRowCount() > 0) { + rowContainer = header; + } else if (body.getRowCount() > 0) { + rowContainer = body; + } else if (footer.getRowCount() > 0) { + rowContainer = footer; + } else { + return false; + } + + double sumOfCellWidths = 0; + TableRowElement tr = rowContainer.getElement().getRows().getItem(0); + + if (tr == null) { + /* + * for some weird reason, the row might be null at this point in + * (some?) webkit browsers. + */ + return false; + } + + NodeList<TableCellElement> cells = tr.getCells(); + assert cells != null : "cells was null, why is it null?"; + + for (int i = 0; i < cells.getLength(); i++) { + TableCellElement cell = cells.getItem(i); + if (!cell.getStyle().getDisplay() + .equals(Display.NONE.getCssName())) { + sumOfCellWidths += WidgetUtil.getBoundingClientRect(cell) + .getWidth(); + } + } + + double rowWidth = WidgetUtil.getBoundingClientRect(tr).getWidth(); + return sumOfCellWidths >= rowWidth; + } + + private void fixSubpixelBrowserBug() { + assert columnConfiguration.getColumnCount() > 0 : "Why are we running this code if there are no columns?"; + + adjustBookkeepingPixels(-SUBPIXEL_ADJUSTMENT); + + fixSubpixelBrowserBugFor(header); + fixSubpixelBrowserBugFor(body); + fixSubpixelBrowserBugFor(footer); + } + + private void adjustBookkeepingPixels(double adjustment) { + int lastColumnIndex = columnConfiguration.columns.size() - 1; + if (lastColumnIndex < 0) { + return; + } + + columnConfiguration.columns.get(lastColumnIndex).calculatedWidth += adjustment; + if (columnConfiguration.widthsArray != null) { + columnConfiguration.widthsArray[lastColumnIndex] += adjustment; + } + } + + /** + * Adjust the last non-spanned cell by {@link #SUBPIXEL_ADJUSTMENT} ( + * {@value #SUBPIXEL_ADJUSTMENT}px). + * <p> + * We'll do this brute-force, by individually measuring and shrinking + * the last non-spanned cell. Brute-force, since each row might be + * spanned differently - we can't simply pick one index and one width, + * and mass-apply that to everything :( + */ + private void fixSubpixelBrowserBugFor(RowContainer rowContainer) { + if (rowContainer.getRowCount() == 0) { + return; + } + + NodeList<TableRowElement> rows = rowContainer.getElement() + .getRows(); + for (int i = 0; i < rows.getLength(); i++) { + + NodeList<TableCellElement> cells = rows.getItem(i).getCells(); + TableCellElement lastNonspannedCell = null; + for (int j = cells.getLength() - 1; j >= 0; j--) { + TableCellElement cell = cells.getItem(j); + if (!cell.getStyle().getDisplay() + .equals(Display.NONE.getCssName())) { + lastNonspannedCell = cell; + break; + } + } + + assert lastNonspannedCell != null : "all cells were \"display: none\" on row " + + i + " in " + rowContainer.getElement().getTagName(); + + double cellWidth = WidgetUtil.getBoundingClientRect( + lastNonspannedCell).getWidth(); + double newWidth = cellWidth - SUBPIXEL_ADJUSTMENT; + lastNonspannedCell.getStyle().setWidth(newWidth, Unit.PX); + } + } + } + // abs(atan(y/x))*(180/PI) = n deg, x = 1, solve y /** * The solution to @@ -4346,6 +4492,8 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } }; + private final SubpixelBrowserBugDetector subpixelBrowserBugDetector = new SubpixelBrowserBugDetector(); + /** * Creates a new Escalator widget instance. */ @@ -4359,6 +4507,46 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker final Element root = DOM.createDiv(); setElement(root); + setupScrollbars(root); + + tableWrapper = DivElement.as(DOM.createDiv()); + + root.appendChild(tableWrapper); + + final Element table = DOM.createTable(); + tableWrapper.appendChild(table); + + table.appendChild(headElem); + table.appendChild(bodyElem); + table.appendChild(footElem); + + Style hCornerStyle = headerDeco.getStyle(); + hCornerStyle.setWidth(verticalScrollbar.getScrollbarThickness(), + Unit.PX); + hCornerStyle.setDisplay(Display.NONE); + root.appendChild(headerDeco); + + Style fCornerStyle = footerDeco.getStyle(); + fCornerStyle.setWidth(verticalScrollbar.getScrollbarThickness(), + Unit.PX); + fCornerStyle.setDisplay(Display.NONE); + root.appendChild(footerDeco); + + Style hWrapperStyle = horizontalScrollbarDeco.getStyle(); + hWrapperStyle.setDisplay(Display.NONE); + hWrapperStyle.setHeight(horizontalScrollbar.getScrollbarThickness(), + Unit.PX); + root.appendChild(horizontalScrollbarDeco); + + setStylePrimaryName("v-escalator"); + + // init default dimensions + setHeight(null); + setWidth(null); + } + + private void setupScrollbars(final Element root) { + ScrollHandler scrollHandler = new ScrollHandler() { @Override public void onScroll(ScrollEvent event) { @@ -4413,40 +4601,20 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker } }); - tableWrapper = DivElement.as(DOM.createDiv()); - - root.appendChild(tableWrapper); - - final Element table = DOM.createTable(); - tableWrapper.appendChild(table); - - table.appendChild(headElem); - table.appendChild(bodyElem); - table.appendChild(footElem); - - Style hCornerStyle = headerDeco.getStyle(); - hCornerStyle.setWidth(verticalScrollbar.getScrollbarThickness(), - Unit.PX); - hCornerStyle.setDisplay(Display.NONE); - root.appendChild(headerDeco); - - Style fCornerStyle = footerDeco.getStyle(); - fCornerStyle.setWidth(verticalScrollbar.getScrollbarThickness(), - Unit.PX); - fCornerStyle.setDisplay(Display.NONE); - root.appendChild(footerDeco); - - Style hWrapperStyle = horizontalScrollbarDeco.getStyle(); - hWrapperStyle.setDisplay(Display.NONE); - hWrapperStyle.setHeight(horizontalScrollbar.getScrollbarThickness(), - Unit.PX); - root.appendChild(horizontalScrollbarDeco); - - setStylePrimaryName("v-escalator"); - - // init default dimensions - setHeight(null); - setWidth(null); + /* + * Because of all the IE hacks we've done above, we now have scrollbars + * hiding underneath a lot of DOM elements. + * + * This leads to problems with OSX (and many touch-only devices) when + * scrollbars are only shown when scrolling, as the scrollbar elements + * are hidden underneath everything. We trust that the scrollbars behave + * properly in these situations and simply pop them out with a bit of + * z-indexing. + */ + if (WidgetUtil.getNativeScrollbarSize() == 0) { + verticalScrollbar.getElement().getStyle().setZIndex(90); + horizontalScrollbar.getElement().getStyle().setZIndex(90); + } } @Override @@ -4459,7 +4627,28 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker header.paintInsertRows(0, header.getRowCount()); footer.paintInsertRows(0, footer.getRowCount()); - recalculateElementSizes(); + + // recalculateElementSizes(); + + Scheduler.get().scheduleDeferred(new Command() { + @Override + public void execute() { + /* + * Not a faintest idea why we have to defer this call, but + * unless it is deferred, the size of the escalator will be 0x0 + * after it is first detached and then reattached to the DOM. + * This only applies to a bare Escalator; inside a Grid + * everything works fine either way. + * + * The three autodetectRowHeightLater calls above seem obvious + * suspects at first. However, they don't seem to have anything + * to do with the issue, as they are no-ops in the + * detach-reattach case. + */ + recalculateElementSizes(); + } + }); + /* * Note: There's no need to explicitly insert rows into the body. * @@ -4486,6 +4675,9 @@ public class Escalator extends Widget implements RequiresResize, DeferredWorker footer.reapplyColumnWidths(); } + verticalScrollbar.onLoad(); + horizontalScrollbar.onLoad(); + scroller.attachScrollListener(verticalScrollbar.getElement()); scroller.attachScrollListener(horizontalScrollbar.getElement()); scroller.attachMousewheelListener(getElement()); diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index 07c888e936..7b336ff5ee 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -65,6 +65,7 @@ import com.google.gwt.user.client.ui.HasEnabled; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.ResizeComposite; import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; import com.vaadin.client.WidgetUtil; import com.vaadin.client.data.DataChangeHandler; @@ -2471,29 +2472,6 @@ public class Grid<T> extends ResizeComposite implements applyColumnWidths(); } else { applyColumnWidthsWithExpansion(); - - /* - * [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: just - * dump all the remaining pixels into the last column and - * whistle loudly - */ - boolean dumpIntoLastColumn = false; - double escalatorWidth = escalator.getInnerWidth(); - double occupiedWidth = 0; - for (Column column : getColumns()) { - occupiedWidth += column.getWidthActual(); - if (column.getWidth() < 0 && column.getExpandRatio() != 0) { - dumpIntoLastColumn = true; - } - } - - if (dumpIntoLastColumn) { - Column<?, T> lastColumn = getColumn(getColumnCount() - 1); - double width = Math.floor(lastColumn.getWidthActual() - + (escalatorWidth - occupiedWidth)); - escalator.getColumnConfiguration().setColumnWidth( - getColumnCount() - 1, width); - } } } @@ -2550,10 +2528,12 @@ public class Grid<T> extends ResizeComposite implements } private void applyColumnWidthsWithExpansion() { - boolean someColumnExpands = false; + boolean defaultExpandRatios = true; int totalRatios = 0; double reservedPixels = 0; - final Set<Column<?, ?>> columnsToExpand = new HashSet<Column<?, ?>>(); + final Set<Column<?, T>> columnsToExpand = new HashSet<Column<?, T>>(); + List<Column<?, T>> nonFixedColumns = new ArrayList<Column<?, T>>(); + Map<Integer, Double> columnSizes = new HashMap<Integer, Double>(); /* * Set all fixed widths and also calculate the size-to-fit widths @@ -2562,49 +2542,37 @@ public class Grid<T> extends ResizeComposite implements * This way we know with how many pixels we have left to expand the * rest. */ - for (Column<?, ?> column : getColumns()) { + for (Column<?, T> column : getColumns()) { final double widthAsIs = column.getWidth(); final boolean isFixedWidth = widthAsIs >= 0; final double widthFixed = Math.max(widthAsIs, column.getMinimumWidth()); - final int expandRatio = column.getExpandRatio(); + defaultExpandRatios = defaultExpandRatios + && column.getExpandRatio() == -1; if (isFixedWidth) { - column.doSetWidth(widthFixed); + columnSizes.put(indexOfColumn(column), widthFixed); + reservedPixels += widthFixed; } else { - column.doSetWidth(-1); - final double newWidth = column.getWidthActual(); - final double maxWidth = getMaxWidth(column); - boolean shouldExpand = newWidth < maxWidth - && expandRatio > 0; - if (shouldExpand) { - totalRatios += expandRatio; - columnsToExpand.add(column); - someColumnExpands = true; - } + nonFixedColumns.add(column); + columnSizes.put(indexOfColumn(column), -1.0d); } - reservedPixels += column.getWidthActual(); } - /* - * If no column has a positive expand ratio, all columns with a - * negative expand ratio has an expand ratio. Columns with 0 expand - * ratio are excluded. - * - * This means that if we only define one column to have 0 expand, it - * will be the only one not to expand, while all the others expand. - */ - if (!someColumnExpands) { - assert totalRatios == 0 : "totalRatios should've been 0"; - assert columnsToExpand.isEmpty() : "columnsToExpand should've been empty"; - for (Column<?, ?> column : getColumns()) { - final double width = column.getWidth(); - final int expandRatio = column.getExpandRatio(); - if (width < 0 && expandRatio < 0) { - totalRatios++; - columnsToExpand.add(column); - } + setColumnSizes(columnSizes); + + for (Column<?, T> column : nonFixedColumns) { + final int expandRatio = (defaultExpandRatios ? 1 : column + .getExpandRatio()); + final double newWidth = column.getWidthActual(); + final double maxWidth = getMaxWidth(column); + boolean shouldExpand = newWidth < maxWidth && expandRatio > 0; + if (shouldExpand) { + totalRatios += expandRatio; + columnsToExpand.add(column); } + reservedPixels += newWidth; + columnSizes.put(indexOfColumn(column), newWidth); } /* @@ -2612,8 +2580,7 @@ public class Grid<T> extends ResizeComposite implements * can distribute the remaining pixels to all columns according to * their expand ratios. */ - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: ceil - double pixelsToDistribute = Math.ceil(escalator.getInnerWidth()) + double pixelsToDistribute = escalator.getInnerWidth() - reservedPixels; if (pixelsToDistribute <= 0 || totalRatios <= 0) { return; @@ -2627,30 +2594,30 @@ public class Grid<T> extends ResizeComposite implements boolean aColumnHasMaxedOut; do { aColumnHasMaxedOut = false; - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME floor - final double widthPerRatio = Math.floor(pixelsToDistribute - / totalRatios); - final Iterator<Column<?, ?>> i = columnsToExpand.iterator(); + final double widthPerRatio = pixelsToDistribute / totalRatios; + final Iterator<Column<?, T>> i = columnsToExpand.iterator(); while (i.hasNext()) { - final Column<?, ?> column = i.next(); + final Column<?, T> column = i.next(); final int expandRatio = getExpandRatio(column, - someColumnExpands); - final double autoWidth = column.getWidthActual(); + defaultExpandRatios); + final double autoWidth = columnSizes + .get(indexOfColumn(column)); final double maxWidth = getMaxWidth(column); - final double widthCandidate = autoWidth + widthPerRatio + double expandedWidth = autoWidth + widthPerRatio * expandRatio; - if (maxWidth <= widthCandidate) { - column.doSetWidth(maxWidth); - totalRatios -= expandRatio; - pixelsToDistribute -= maxWidth - autoWidth; + if (maxWidth <= expandedWidth) { i.remove(); + totalRatios -= expandRatio; aColumnHasMaxedOut = true; + pixelsToDistribute -= maxWidth - autoWidth; + columnSizes.put(indexOfColumn(column), maxWidth); } } } while (aColumnHasMaxedOut); if (totalRatios <= 0 && columnsToExpand.isEmpty()) { + setColumnSizes(columnSizes); return; } assert pixelsToDistribute > 0 : "We've run out of pixels to distribute (" @@ -2665,16 +2632,28 @@ public class Grid<T> extends ResizeComposite implements * If we still have anything left, distribute the remaining pixels * to the remaining columns. */ - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: floor - final double widthPerRatio = Math.floor(pixelsToDistribute - / totalRatios); - for (Column<?, ?> column : columnsToExpand) { + final double widthPerRatio; + int leftOver = 0; + if (BrowserInfo.get().isIE8() || BrowserInfo.get().isIE9() + || BrowserInfo.getBrowserString().contains("PhantomJS")) { + // These browsers report subpixels as integers. this usually + // results into issues.. + widthPerRatio = (int) (pixelsToDistribute / totalRatios); + leftOver = (int) (pixelsToDistribute - widthPerRatio + * totalRatios); + } else { + widthPerRatio = pixelsToDistribute / totalRatios; + } + for (Column<?, T> column : columnsToExpand) { final int expandRatio = getExpandRatio(column, - someColumnExpands); - final double autoWidth = column.getWidthActual(); - final double totalWidth = autoWidth + widthPerRatio - * expandRatio; - column.doSetWidth(totalWidth); + defaultExpandRatios); + final double autoWidth = columnSizes.get(indexOfColumn(column)); + double totalWidth = autoWidth + widthPerRatio * expandRatio; + if (leftOver > 0) { + totalWidth += 1; + leftOver--; + } + columnSizes.put(indexOfColumn(column), totalWidth); totalRatios -= expandRatio; } @@ -2703,12 +2682,12 @@ public class Grid<T> extends ResizeComposite implements * wouldn't show up in that set. */ - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME ceil - double minWidth = Math.ceil(getMinWidth(column)); - double currentWidth = column.getWidthActual(); + double minWidth = getMinWidth(column); + double currentWidth = columnSizes + .get(indexOfColumn(column)); boolean hasAutoWidth = column.getWidth() < 0; if (hasAutoWidth && currentWidth < minWidth) { - column.doSetWidth(minWidth); + columnSizes.put(indexOfColumn(column), minWidth); pixelsToRemoveFromOtherColumns += (minWidth - currentWidth); minWidthsCausedReflows = true; @@ -2727,27 +2706,36 @@ public class Grid<T> extends ResizeComposite implements */ totalRatios = 0; for (Column<?, ?> column : columnsToExpand) { - totalRatios += getExpandRatio(column, someColumnExpands); + totalRatios += getExpandRatio(column, defaultExpandRatios); } - // [[subpixelworkaround]] (6.2.2015, Henrik Paul) FIXME: ceil - final double pixelsToRemovePerRatio = Math - .ceil(pixelsToRemoveFromOtherColumns / totalRatios); - for (Column<?, ?> column : columnsToExpand) { + final double pixelsToRemovePerRatio = pixelsToRemoveFromOtherColumns + / totalRatios; + for (Column<?, T> column : columnsToExpand) { final double pixelsToRemove = pixelsToRemovePerRatio - * getExpandRatio(column, someColumnExpands); - column.doSetWidth(column.getWidthActual() - pixelsToRemove); + * getExpandRatio(column, defaultExpandRatios); + int colIndex = indexOfColumn(column); + columnSizes.put(colIndex, columnSizes.get(colIndex) + - pixelsToRemove); } } while (minWidthsCausedReflows); + + // Finally set all the column sizes. + setColumnSizes(columnSizes); + } + + private void setColumnSizes(Map<Integer, Double> columnSizes) { + // Set all widths at once + escalator.getColumnConfiguration().setColumnWidths(columnSizes); } private int getExpandRatio(Column<?, ?> column, - boolean someColumnExpands) { + boolean defaultExpandRatios) { int expandRatio = column.getExpandRatio(); if (expandRatio > 0) { return expandRatio; } else if (expandRatio < 0) { - assert !someColumnExpands : "No columns should've expanded"; + assert defaultExpandRatios : "No columns should've expanded"; return 1; } else { assert false : "this method should've not been called at all if expandRatio is 0"; @@ -3463,11 +3451,11 @@ public class Grid<T> extends ResizeComposite implements } if (this.grid != null) { - this.grid.autoColumnWidthsRecalculator.schedule(); + this.grid.recalculateColumnWidths(); } this.grid = grid; if (this.grid != null) { - this.grid.autoColumnWidthsRecalculator.schedule(); + this.grid.recalculateColumnWidths(); updateHeader(); } } @@ -3611,7 +3599,7 @@ public class Grid<T> extends ResizeComposite implements } void reapplyWidth() { - setWidth(getWidth()); + scheduleColumnWidthRecalculator(); } /** @@ -3851,7 +3839,7 @@ public class Grid<T> extends ResizeComposite implements private void scheduleColumnWidthRecalculator() { if (grid != null) { - grid.autoColumnWidthsRecalculator.schedule(); + grid.recalculateColumnWidths(); } else { /* * NOOP @@ -6715,6 +6703,21 @@ public class Grid<T> extends ResizeComposite implements } } + @Override + public void onResize() { + super.onResize(); + /* + * Delay calculation to be deferred so Escalator can do it's magic. + */ + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + + @Override + public void execute() { + recalculateColumnWidths(); + } + }); + } + /** * Grid does not support adding Widgets this way. * <p> @@ -6812,4 +6815,17 @@ public class Grid<T> extends ResizeComposite implements public void resetSizesFromDom() { getEscalator().resetSizesFromDom(); } + + /** + * Requests that the column widths should be recalculated. + * <p> + * The actual recalculation is not necessarily done immediately so you + * cannot rely on the columns being the correct width after the call + * returns. + * + * @since 7.4.1 + */ + public void recalculateColumnWidths() { + autoColumnWidthsRecalculator.schedule(); + } } diff --git a/common.xml b/common.xml index 8c2919972d..9487560051 100644 --- a/common.xml +++ b/common.xml @@ -163,6 +163,7 @@ <param name="bundle-name" value="${module.name}" /> <param name="bundle-symbolic" value="${module.symbolic}" /> <param name="bundle-vendor" value="${vaadin.vendor}" /> + <param name="includeNumberPackages" value="${osgi.includeNumberPackages}" /> </antcall> </target> @@ -174,7 +175,7 @@ <fail unless="bundle-symbolic" message="No bundle-symbolic parameter given" /> <fail unless="bundle-version" message="No bundle-version parameter given" /> <fail unless="bundle-vendor" message="No bundle-vendor parameter given" /> - + <fail unless="includeNumberPackages" message="No includeNumberPackages parameter given" /> <property name="bundle-manifestversion" value="2" /> <jar file="${jar}" update="true"> @@ -228,6 +229,7 @@ <arg line="com/vaadin com/google ${osgi.extra.package.prefixes}" /> <classpath refid="buildhelpers.classpath" /> <jvmarg value="-Dvaadin.version=${vaadin.version}" /> + <jvmarg value="-DincludeNumberPackages=${includeNumberPackages}" /> </java> </target> diff --git a/eclipse/Super Development Mode (vaadin).launch b/eclipse/Super Development Mode (vaadin).launch index b57410bfd6..9f4da19a74 100644 --- a/eclipse/Super Development Mode (vaadin).launch +++ b/eclipse/Super Development Mode (vaadin).launch @@ -21,7 +21,7 @@ </listAttribute> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.codeserver.CodeServer"/> -<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="com.vaadin.DefaultWidgetSet -bindAddress 0.0.0.0"/> +<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-noprecompile -bindAddress 0.0.0.0 com.vaadin.DefaultWidgetSet com.vaadin.tests.widgetset.TestingWidgetSet"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="vaadin"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx512M -XX:MaxPermSize=256M"/> </launchConfiguration> diff --git a/ivysettings.xml b/ivysettings.xml index bc60be5e29..f1fc4d1c63 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/push/build.xml b/push/build.xml index 9afe76620c..519dc81ed2 100644 --- a/push/build.xml +++ b/push/build.xml @@ -18,7 +18,7 @@ location="${result.dir}/js/VAADIN/vaadinPush.debug.js" /> <!-- Keep the version number in sync with ivy.xml, server/src/com/vaadin/server/Constants.java --> - <property name="atmosphere.runtime.version" value="2.2.4.vaadin2" /> + <property name="atmosphere.runtime.version" value="2.2.4.vaadin4" /> <property name="jquery.js" location="lib/jquery/jquery-1.11.0.js" /> <path id="classpath.compile.custom" /> diff --git a/push/ivy.xml b/push/ivy.xml index b899b34af7..c285bfd4aa 100644 --- a/push/ivy.xml +++ b/push/ivy.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ivy-module [ <!-- Keep the version number in sync with build.xml --> - <!ENTITY atmosphere.runtime.version "2.2.4.vaadin2"> + <!ENTITY atmosphere.runtime.version "2.2.4.vaadin4"> <!ENTITY atmosphere.js.version "2.2.6.vaadin3"> ]> diff --git a/server/build.xml b/server/build.xml index c658ab0336..79bc6debe2 100644 --- a/server/build.xml +++ b/server/build.xml @@ -28,7 +28,7 @@ <property name="server.osgi.import" value="javax.servlet;version="2.4.0",javax.servlet.http;version="2.4.0",javax.validation;version="1.0.0.GA";resolution:=optional,org.jsoup;version="1.6.3",org.jsoup.parser;version="1.6.3",org.jsoup.nodes;version="1.6.3",org.jsoup.helper;version="1.6.3",org.jsoup.safety;version="1.6.3"" /> <property name="server.osgi.require" - value="com.vaadin.shared;bundle-version="${vaadin.version}",com.vaadin.push;bundle-version="${vaadin.version}";resolution:=optional,com.vaadin.sass-compiler;bundle-version="${vaadin.sass.version}";resolution:=optional" /> + value="com.google.gwt.thirdparty.guava;bundle-version="16.0.1.vaadin1",com.vaadin.shared;bundle-version="${vaadin.version}",com.vaadin.push;bundle-version="${vaadin.version}";resolution:=optional,com.vaadin.sass-compiler;bundle-version="${vaadin.sass.version}";resolution:=optional" /> <antcall target="common.jar"> <param name="require-bundle" value="${server.osgi.require}" /> <param name="import-package" value="${server.osgi.import}" /> diff --git a/server/src/com/vaadin/data/RpcDataProviderExtension.java b/server/src/com/vaadin/data/RpcDataProviderExtension.java index 354bfe336c..991cb0537d 100644 --- a/server/src/com/vaadin/data/RpcDataProviderExtension.java +++ b/server/src/com/vaadin/data/RpcDataProviderExtension.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -325,10 +326,10 @@ public class RpcDataProviderExtension extends AbstractExtension { */ private class ActiveRowHandler implements Serializable { /** - * A map from itemId to the value change listener used for all of its + * A map from index to the value change listener used for all of column * properties */ - private final Map<Object, GridValueChangeListener> valueChangeListeners = new HashMap<Object, GridValueChangeListener>(); + private final Map<Integer, GridValueChangeListener> valueChangeListeners = new HashMap<Integer, GridValueChangeListener>(); /** * The currently active range. Practically, it's the range of row @@ -388,36 +389,27 @@ public class RpcDataProviderExtension extends AbstractExtension { } private void addValueChangeListeners(Range range) { - for (int i = range.getStart(); i < range.getEnd(); i++) { + for (Integer i = range.getStart(); i < range.getEnd(); i++) { final Object itemId = container.getIdByIndex(i); final Item item = container.getItem(itemId); - if (valueChangeListeners.containsKey(itemId)) { - /* - * This might occur when items are removed from above the - * viewport, the escalator scrolls up to compensate, but the - * same items remain in the view: It looks as if one row was - * scrolled, when in fact the whole viewport was shifted up. - */ - continue; - } + assert valueChangeListeners.get(i) == null : "Overwriting existing listener"; GridValueChangeListener listener = new GridValueChangeListener( itemId, item); - valueChangeListeners.put(itemId, listener); + valueChangeListeners.put(i, listener); } } private void removeValueChangeListeners(Range range) { - for (int i = range.getStart(); i < range.getEnd(); i++) { - final Object itemId = container.getIdByIndex(i); + for (Integer i = range.getStart(); i < range.getEnd(); i++) { final GridValueChangeListener listener = valueChangeListeners - .remove(itemId); + .remove(i); - if (listener != null) { - listener.removeListener(); - } + assert listener != null : "Trying to remove nonexisting listener"; + + listener.removeListener(); } } @@ -478,12 +470,16 @@ public class RpcDataProviderExtension extends AbstractExtension { */ public void insertRows(int firstIndex, int count) { if (firstIndex < activeRange.getStart()) { + moveListeners(activeRange, count); activeRange = activeRange.offsetBy(count); } else if (firstIndex < activeRange.getEnd()) { - final Range deprecatedRange = Range.withLength( - activeRange.getEnd(), count); - removeValueChangeListeners(deprecatedRange); - + int end = activeRange.getEnd(); + // Move rows from first added index by count + Range movedRange = Range.between(firstIndex, end); + moveListeners(movedRange, count); + // Remove excess listeners from extra rows + removeValueChangeListeners(Range.withLength(end, count)); + // Add listeners for new rows final Range freshRange = Range.withLength(firstIndex, count); addValueChangeListeners(freshRange); } else { @@ -509,23 +505,52 @@ public class RpcDataProviderExtension extends AbstractExtension { public void removeRows(int firstIndex, int count) { Range removed = Range.withLength(firstIndex, count); if (removed.intersects(activeRange)) { - final Range deprecated = removed.restrictTo(activeRange); - for (int i = deprecated.getStart(); i < deprecated.getEnd(); ++i) { - Object itemId = keyMapper.itemIdAtIndex(i); - // Item doesn't exist anymore. - valueChangeListeners.remove(itemId); - } + final Range[] deprecated = activeRange.partitionWith(removed); + // Remove the listeners that are no longer existing + removeValueChangeListeners(deprecated[1]); + // Move remaining listeners to fill the listener map correctly + moveListeners(deprecated[2], -deprecated[1].length()); activeRange = Range.withLength(activeRange.getStart(), - activeRange.length() - deprecated.length()); + activeRange.length() - deprecated[1].length()); + } else { if (removed.getEnd() < activeRange.getStart()) { /* firstIndex < lastIndex < start */ + moveListeners(activeRange, -count); activeRange = activeRange.offsetBy(-count); } /* else: end <= firstIndex, no need to do anything */ } } + + /** + * Moves value change listeners in map with given index range by count + */ + private void moveListeners(Range movedRange, int diff) { + if (diff < 0) { + for (Integer i = movedRange.getStart(); i < movedRange.getEnd(); ++i) { + moveListener(i, i + diff); + } + } else if (diff > 0) { + for (Integer i = movedRange.getEnd() - 1; i >= movedRange + .getStart(); --i) { + moveListener(i, i + diff); + } + } else { + // diff == 0 should not happen. If it does, should be no-op + return; + } + } + + private void moveListener(Integer oldIndex, Integer newIndex) { + assert valueChangeListeners.get(newIndex) == null : "Overwriting existing listener"; + + GridValueChangeListener listener = valueChangeListeners + .remove(oldIndex); + assert listener != null : "Moving nonexisting listener."; + valueChangeListeners.put(newIndex, listener); + } } /** @@ -663,7 +688,7 @@ public class RpcDataProviderExtension extends AbstractExtension { * taking all the corner cases into account. */ - Map<Object, GridValueChangeListener> listeners = activeRowHandler.valueChangeListeners; + Map<Integer, GridValueChangeListener> listeners = activeRowHandler.valueChangeListeners; for (GridValueChangeListener listener : listeners.values()) { listener.removeListener(); } @@ -691,7 +716,7 @@ public class RpcDataProviderExtension extends AbstractExtension { private CellReference cellReference; /** Set of updated item ids */ - private Set<Object> updatedItemIds = new HashSet<Object>(); + private Set<Object> updatedItemIds = new LinkedHashSet<Object>(); /** * Queued RPC calls for adding and removing rows. Queue will be handled in diff --git a/server/src/com/vaadin/server/Constants.java b/server/src/com/vaadin/server/Constants.java index 8036490333..b9a43a98de 100644 --- a/server/src/com/vaadin/server/Constants.java +++ b/server/src/com/vaadin/server/Constants.java @@ -67,7 +67,7 @@ public interface Constants { // Keep the version number in sync with push/build.xml and other locations // listed in that file - static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.4.vaadin2"; + static final String REQUIRED_ATMOSPHERE_RUNTIME_VERSION = "2.2.4.vaadin4"; static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n" + "=================================================================\n" @@ -132,11 +132,12 @@ public interface Constants { static final String SERVLET_PARAMETER_RESOURCE_CACHE_TIME = "resourceCacheTime"; static final String SERVLET_PARAMETER_HEARTBEAT_INTERVAL = "heartbeatInterval"; static final String SERVLET_PARAMETER_CLOSE_IDLE_SESSIONS = "closeIdleSessions"; - static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode"; static final String SERVLET_PARAMETER_UI_PROVIDER = "UIProvider"; static final String SERVLET_PARAMETER_LEGACY_PROPERTY_TOSTRING = "legacyPropertyToString"; static final String SERVLET_PARAMETER_SYNC_ID_CHECK = "syncIdCheck"; static final String SERVLET_PARAMETER_SENDURLSASPARAMETERS = "sendUrlsAsParameters"; + static final String SERVLET_PARAMETER_PUSH_MODE = "pushMode"; + static final String SERVLET_PARAMETER_PUSH_PATH = "pushPath"; // Configurable parameter names static final String PARAMETER_VAADIN_RESOURCES = "Resources"; diff --git a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java index b26e048431..5402979be8 100644 --- a/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DefaultDeploymentConfiguration.java @@ -61,6 +61,13 @@ public class DefaultDeploymentConfiguration extends public static final boolean DEFAULT_SEND_URLS_AS_PARAMETERS = true; + /** + * Default value for {@link #getPushPath()} = {@value} . + * + * @since 7.4.1 + */ + public static final String DEFAULT_PUSH_PATH = "PUSH"; + private final Properties initParameters; private boolean productionMode; private boolean xsrfProtectionEnabled; @@ -285,6 +292,18 @@ public class DefaultDeploymentConfiguration extends } /** + * {@inheritDoc} + * <p> + * The default path {@link DEFAULT_PUSH_PATH} can be changed by using init + * parameter {@link Constants.SERVLET_PARAMETER_PUSH_PATH}. + */ + @Override + public String getPushPath() { + return getApplicationOrSystemProperty( + Constants.SERVLET_PARAMETER_PUSH_PATH, DEFAULT_PUSH_PATH); + } + + /** * Log a warning if Vaadin is not running in production mode. */ private void checkProductionMode() { diff --git a/server/src/com/vaadin/server/DeploymentConfiguration.java b/server/src/com/vaadin/server/DeploymentConfiguration.java index 968ec7c0c3..06556e28a7 100644 --- a/server/src/com/vaadin/server/DeploymentConfiguration.java +++ b/server/src/com/vaadin/server/DeploymentConfiguration.java @@ -195,7 +195,7 @@ public interface DeploymentConfiguration extends Serializable { * * @since 7.4 * - * @return UI class name + * @return the name of the widgetset */ public String getWidgetset(String defaultValue); @@ -214,6 +214,14 @@ public interface DeploymentConfiguration extends Serializable { public String getClassLoaderName(); /** + * Returns the push path configuration option value. Should never be null. + * + * @since 7.4.1 + * @return the path used with server push + */ + public String getPushPath(); + + /** * Returns to legacy Property.toString() mode used. See * {@link AbstractProperty#isLegacyToStringEnabled()} for more information. * diff --git a/server/src/com/vaadin/server/ServletPortletHelper.java b/server/src/com/vaadin/server/ServletPortletHelper.java index 197d9fe416..1f0c7f02b9 100644 --- a/server/src/com/vaadin/server/ServletPortletHelper.java +++ b/server/src/com/vaadin/server/ServletPortletHelper.java @@ -124,7 +124,8 @@ public class ServletPortletHelper implements Serializable { } public static boolean isPushRequest(VaadinRequest request) { - return hasPathPrefix(request, ApplicationConstants.PUSH_PATH + '/'); + return hasPathPrefix(request, request.getService() + .getDeploymentConfiguration().getPushPath() + '/'); } public static void initDefaultUIProvider(VaadinSession session, diff --git a/server/src/com/vaadin/server/VaadinService.java b/server/src/com/vaadin/server/VaadinService.java index 36d6910a7a..74f0051e30 100644 --- a/server/src/com/vaadin/server/VaadinService.java +++ b/server/src/com/vaadin/server/VaadinService.java @@ -1433,6 +1433,10 @@ public abstract class VaadinService implements Serializable { ErrorHandler errorHandler = ErrorEvent .findErrorHandler(vaadinSession); + if (errorHandler != null) { + errorHandler.error(new ErrorEvent(t)); + } + // if this was an UIDL request, send UIDL back to the client if (ServletPortletHelper.isUIDLRequest(request)) { SystemMessages ci = getSystemMessages( @@ -1454,14 +1458,7 @@ public abstract class VaadinService implements Serializable { "Failed to write critical notification response to the client", e); } - if (errorHandler != null) { - errorHandler.error(new ErrorEvent(t)); - } } else { - if (errorHandler != null) { - errorHandler.error(new ErrorEvent(t)); - } - // Re-throw other exceptions throw new ServiceException(t); } @@ -1574,20 +1571,11 @@ public abstract class VaadinService implements Serializable { String message, String details, String url) { String returnString = ""; try { - if (message == null) { - message = details; - } else if (details != null) { - message += "<br/><br/>" + details; - } - JsonObject appError = Json.createObject(); - appError.put("caption", caption); - appError.put("message", message); - if (url == null) { - appError.put("url", Json.createNull()); - } else { - appError.put("url", url); - } + putValueOrJsonNull(appError, "caption", caption); + putValueOrJsonNull(appError, "url", url); + putValueOrJsonNull(appError, "message", + createCriticalNotificationMessage(message, details)); JsonObject meta = Json.createObject(); meta.put("appError", appError); @@ -1607,6 +1595,26 @@ public abstract class VaadinService implements Serializable { return "for(;;);[" + returnString + "]"; } + private static String createCriticalNotificationMessage(String message, + String details) { + if (message == null) { + return details; + } else if (details != null) { + return message + "<br/><br/>" + details; + } + + return message; + } + + private static void putValueOrJsonNull(JsonObject json, String key, + String value) { + if (value == null) { + json.put(key, Json.createNull()); + } else { + json.put(key, value); + } + } + /** * @deprecated As of 7.0. Will likely change or be removed in a future * version diff --git a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java index 0819a24ee9..357278f411 100644 --- a/server/src/com/vaadin/server/communication/AtmospherePushConnection.java +++ b/server/src/com/vaadin/server/communication/AtmospherePushConnection.java @@ -275,12 +275,10 @@ public class AtmospherePushConnection implements PushConnection { assert isConnected(); if (resource.isResumed()) { - // Calling disconnect may end up invoking it again via - // resource.resume and PushHandler.onResume. Bail out here if - // the resource is already resumed; this is a bit hacky and should - // be implemented in a better way in 7.2. - resource = null; - state = State.DISCONNECTED; + // This can happen for long polling because of + // http://dev.vaadin.com/ticket/16919 + // Once that is fixed, this should never happen + connectionLost(); return; } @@ -307,8 +305,23 @@ public class AtmospherePushConnection implements PushConnection { getLogger() .log(Level.INFO, "Error when closing push connection", e); } + connectionLost(); + } + + /** + * Called when the connection to the client has been lost. + * + * @since 7.4.1 + */ + public void connectionLost() { resource = null; - state = State.DISCONNECTED; + if (state == State.CONNECTED) { + // Guard against connectionLost being (incorrectly) called when + // state is PUSH_PENDING or RESPONSE_PENDING + // (http://dev.vaadin.com/ticket/16919) + state = State.DISCONNECTED; + } + } /** diff --git a/server/src/com/vaadin/server/communication/PushHandler.java b/server/src/com/vaadin/server/communication/PushHandler.java index 6ee81270cd..22eee70aa0 100644 --- a/server/src/com/vaadin/server/communication/PushHandler.java +++ b/server/src/com/vaadin/server/communication/PushHandler.java @@ -28,6 +28,7 @@ import org.atmosphere.cpr.AtmosphereResource; import org.atmosphere.cpr.AtmosphereResource.TRANSPORT; import org.atmosphere.cpr.AtmosphereResourceEvent; import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter; +import org.atmosphere.cpr.AtmosphereResourceImpl; import org.atmosphere.handler.AbstractReflectorAtmosphereHandler; import com.vaadin.server.ErrorEvent; @@ -45,6 +46,7 @@ import com.vaadin.server.VaadinSession; import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.communication.PushMode; import com.vaadin.ui.UI; + import elemental.json.JsonException; /** @@ -62,7 +64,7 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { throws IOException { super.onStateChange(event); if (event.isCancelled() || event.isResumedOnTimeout()) { - disconnect(event); + connectionLost(event); } } @@ -327,17 +329,17 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { public void onDisconnect(AtmosphereResourceEvent event) { // Log event on trace level super.onDisconnect(event); - disconnect(event); + connectionLost(event); } @Override public void onThrowable(AtmosphereResourceEvent event) { getLogger().log(Level.SEVERE, "Exception in push connection", event.throwable()); - disconnect(event); + connectionLost(event); } - private void disconnect(AtmosphereResourceEvent event) { + private void connectionLost(AtmosphereResourceEvent event) { // We don't want to use callWithUi here, as it assumes there's a client // request active and does requestStart and requestEnd among other // things. @@ -423,12 +425,8 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { "Connection unexpectedly closed for resource {0} with transport {1}", new Object[] { id, resource.transport() }); } - if (pushConnection.isConnected()) { - // disconnect() assumes the push connection is connected but - // this method can currently be called more than once during - // disconnect, depending on the situation - pushConnection.disconnect(); - } + + pushConnection.connectionLost(); } } catch (final Exception e) { @@ -472,6 +470,15 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { */ private static void sendRefreshAndDisconnect(AtmosphereResource resource) throws IOException { + if (resource instanceof AtmosphereResourceImpl + && !((AtmosphereResourceImpl) resource).isInScope()) { + // The resource is no longer valid so we should not write + // anything to it + getLogger() + .fine("sendRefreshAndDisconnect called for resource no longer in scope"); + return; + } + AtmospherePushConnection connection = new AtmospherePushConnection(null); connection.connect(resource); try { @@ -490,6 +497,14 @@ public class PushHandler extends AtmosphereResourceEventListenerAdapter { AtmosphereResource resource, String notificationJson) { // TODO Implemented differently from sendRefreshAndDisconnect try { + if (resource instanceof AtmosphereResourceImpl + && !((AtmosphereResourceImpl) resource).isInScope()) { + // The resource is no longer valid so we should not write + // anything to it + getLogger() + .fine("sendNotificationAndDisconnect called for resource no longer in scope"); + return; + } resource.getResponse().getWriter().write(notificationJson); resource.resume(); } catch (Exception e) { diff --git a/server/src/com/vaadin/server/communication/UIInitHandler.java b/server/src/com/vaadin/server/communication/UIInitHandler.java index 3a6dc1e55f..02b4e64159 100644 --- a/server/src/com/vaadin/server/communication/UIInitHandler.java +++ b/server/src/com/vaadin/server/communication/UIInitHandler.java @@ -198,10 +198,11 @@ public abstract class UIInitHandler extends SynchronizedRequestHandler { PushMode pushMode = provider.getPushMode(event); if (pushMode == null) { - pushMode = session.getService().getDeploymentConfiguration() - .getPushMode(); + pushMode = session.getConfiguration().getPushMode(); } ui.getPushConfiguration().setPushMode(pushMode); + ui.getPushConfiguration().setPushPath( + session.getConfiguration().getPushPath()); Transport transport = provider.getPushTransport(event); if (transport != null) { diff --git a/server/src/com/vaadin/ui/Flash.java b/server/src/com/vaadin/ui/Flash.java index cd7c00087e..2d0f188b84 100644 --- a/server/src/com/vaadin/ui/Flash.java +++ b/server/src/com/vaadin/ui/Flash.java @@ -97,7 +97,7 @@ public class Flash extends AbstractEmbedded { * Returns the codebase. * * @see #setCodebase(String) - * @since 7.4 + * @since 7.4.1 * @return Current codebase. */ public String getCodebase() { @@ -126,7 +126,7 @@ public class Flash extends AbstractEmbedded { * Returns the current codetype. * * @see #setCodetype(String) - * @since 7.4 + * @since 7.4.1 * @return Current codetype. */ public String getCodetype() { @@ -157,7 +157,7 @@ public class Flash extends AbstractEmbedded { * Returns current archive. * * @see #setArchive(String) - * @since 7.4 + * @since 7.4.1 * @return Current archive. */ public String getArchive() { @@ -181,7 +181,7 @@ public class Flash extends AbstractEmbedded { /** * Returns standby. * - * @since + * @since 7.4.1 * @return Standby string. */ public String getStandby() { @@ -247,7 +247,7 @@ public class Flash extends AbstractEmbedded { * * @see #setParameter(String, String) * @see #getParameter(String) - * @since 7.4 + * @since 7.4.1 * @return An iterable with declared parameter names. */ public Iterable<String> getParameterNames() { diff --git a/server/src/com/vaadin/ui/Grid.java b/server/src/com/vaadin/ui/Grid.java index df64ee85ed..77b57bceda 100644 --- a/server/src/com/vaadin/ui/Grid.java +++ b/server/src/com/vaadin/ui/Grid.java @@ -2251,7 +2251,7 @@ public class Grid extends AbstractComponent implements SelectionNotifier, public Column setLastFrozenColumn() { checkColumnIsAttached(); grid.setFrozenColumnCount(grid.getState(false).columnOrder - .indexOf(this) + 1); + .indexOf(getState().id) + 1); return this; } @@ -5229,4 +5229,17 @@ public class Grid extends AbstractComponent implements SelectionNotifier, public void removeListener(ItemClickListener listener) { removeItemClickListener(listener); } + + /** + * Requests that the column widths should be recalculated. + * <p> + * In most cases Grid will know when column widths need to be recalculated + * but this method can be used to force recalculation in situations when + * grid does not recalculate automatically. + * + * @since 7.4.1 + */ + public void recalculateColumnWidths() { + getRpcProxy(GridClientRpc.class).recalculateColumnWidths(); + } } diff --git a/server/src/com/vaadin/ui/JavaScriptFunction.java b/server/src/com/vaadin/ui/JavaScriptFunction.java index c006a36d58..071c88350b 100644 --- a/server/src/com/vaadin/ui/JavaScriptFunction.java +++ b/server/src/com/vaadin/ui/JavaScriptFunction.java @@ -19,6 +19,7 @@ package com.vaadin.ui; import java.io.Serializable; import com.vaadin.server.AbstractJavaScriptExtension; + import elemental.json.JsonArray; /** @@ -26,9 +27,9 @@ import elemental.json.JsonArray; * the corresponding JavaScript function is called, the {@link #call(JsonArray)} * method is invoked. * - * @see JavaScript#addFunction(String, JavaScriptCallback) - * @see AbstractJavaScriptComponent#addFunction(String, JavaScriptCallback) - * @see AbstractJavaScriptExtension#addFunction(String, JavaScriptCallback) + * @see JavaScript#addFunction(String, JavaScriptFunction) + * @see AbstractJavaScriptComponent#addFunction(String, JavaScriptFunction) + * @see AbstractJavaScriptExtension#addFunction(String, JavaScriptFunction) * * @author Vaadin Ltd * @since 7.0.0 diff --git a/server/src/com/vaadin/ui/PushConfiguration.java b/server/src/com/vaadin/ui/PushConfiguration.java index 90ad28542c..d5e89b4b14 100644 --- a/server/src/com/vaadin/ui/PushConfiguration.java +++ b/server/src/com/vaadin/ui/PushConfiguration.java @@ -105,6 +105,26 @@ public interface PushConfiguration extends Serializable { public void setFallbackTransport(Transport fallbackTransport); /** + * Sets the path that is used with push. + * + * @since 7.4.1 + * @param pushPath + * The path to be used with push + * + * @throws IllegalArgumentException + * if the argument is null or empty. + */ + public void setPushPath(String pushPath); + + /** + * Returns the path used with push. + * + * @since 7.4.1 + * @return The path that is used with push + */ + public String getPushPath(); + + /** * Returns the given parameter, if set. * <p> * This method provides low level access to push parameters and is typically @@ -258,6 +278,32 @@ class PushConfigurationImpl implements PushConfiguration { /* * (non-Javadoc) * + * @see com.vaadin.ui.PushConfiguration#setPushPath(java.lang.String) + */ + @Override + public void setPushPath(String pushPath) { + if (pushPath != null && !pushPath.isEmpty()) { + getState().pushPath = pushPath; + } else { + throw new IllegalArgumentException( + "Push path can't be empty or null"); + } + + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.PushConfiguration#getPushPath() + */ + @Override + public String getPushPath() { + return getState(false).pushPath; + } + + /* + * (non-Javadoc) + * * @see com.vaadin.ui.PushConfiguration#getParameter(java.lang.String) */ @Override @@ -290,5 +336,4 @@ class PushConfigurationImpl implements PushConfiguration { return Collections.unmodifiableCollection(getState(false).parameters .keySet()); } - } diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java index 66ed1a48f4..dad4d295bf 100644 --- a/server/src/com/vaadin/ui/Slider.java +++ b/server/src/com/vaadin/ui/Slider.java @@ -161,6 +161,11 @@ public class Slider extends AbstractField<Double> { */ public void setMax(double max) { getState().maxValue = max; + + if (getMin() > max) { + getState().minValue = max; + } + if (getValue() > max) { setValue(max); } @@ -179,11 +184,16 @@ public class Slider extends AbstractField<Double> { * Set the minimum slider value. If the current value of the slider is * smaller than this, the value is set to the new minimum. * - * @param max + * @param min * The new minimum slider value */ public void setMin(double min) { getState().minValue = min; + + if (getMax() < min) { + getState().maxValue = min; + } + if (getValue() < min) { setValue(min); } @@ -260,12 +270,12 @@ public class Slider extends AbstractField<Double> { newValue = (int) (v * Math.pow(10, resolution)); newValue = newValue / Math.pow(10, resolution); if (getMin() > newValue || getMax() < newValue) { - throw new ValueOutOfBoundsException(value); + throw new ValueOutOfBoundsException(newValue); } } else { newValue = (int) v; if (getMin() > newValue || getMax() < newValue) { - throw new ValueOutOfBoundsException(value); + throw new ValueOutOfBoundsException(newValue); } } @@ -313,6 +323,8 @@ public class Slider extends AbstractField<Double> { * @param valueOutOfBounds */ public ValueOutOfBoundsException(Double valueOutOfBounds) { + super(String.format("Value %s is out of bounds: [%s, %s]", + valueOutOfBounds, getMin(), getMax())); value = valueOutOfBounds; } diff --git a/server/src/com/vaadin/ui/UI.java b/server/src/com/vaadin/ui/UI.java index 66f893e04a..8dd600ddd0 100644 --- a/server/src/com/vaadin/ui/UI.java +++ b/server/src/com/vaadin/ui/UI.java @@ -425,7 +425,12 @@ public abstract class UI extends AbstractSingleComponentContainer implements + "."); } else { if (session == null) { - detach(); + try { + detach(); + } catch (Exception e) { + getLogger().log(Level.WARNING, + "Error while detaching UI from session", e); + } // Disable push when the UI is detached. Otherwise the // push connection and possibly VaadinSession will live on. getPushConfiguration().setPushMode(PushMode.DISABLED); diff --git a/server/src/com/vaadin/ui/declarative/Design.java b/server/src/com/vaadin/ui/declarative/Design.java index dc96e789bf..1b8585e6f6 100644 --- a/server/src/com/vaadin/ui/declarative/Design.java +++ b/server/src/com/vaadin/ui/declarative/Design.java @@ -57,6 +57,119 @@ import com.vaadin.ui.declarative.DesignContext.ComponentCreationListener; * @author Vaadin Ltd */ public class Design implements Serializable { + + /** + * Callback for creating instances of a given component class when reading + * designs. The default implementation, {@link DefaultComponentFactory} will + * use <code>Class.forName(className).newInstance()</code>, which might not + * be suitable e.g. in an OSGi environment or if the Component instances + * should be created as managed CDI beans. + * <p> + * Use {@link Design#setComponentFactory(ComponentFactory)} to configure + * Vaadin to use a custom component factory. + * + * + * @since 7.4.1 + */ + public interface ComponentFactory extends Serializable { + /** + * Creates a component based on the fully qualified name derived from + * the tag name in the design. + * + * @param fullyQualifiedClassName + * the fully qualified name of the component to create + * @param context + * the design context for which the component is created + * + * @return a newly created component + */ + public Component createComponent(String fullyQualifiedClassName, + DesignContext context); + } + + /** + * Default implementation of {@link ComponentFactory}, using + * <code>Class.forName(className).newInstance()</code> for finding the + * component class and creating a component instance. + * + * @since 7.4.1 + */ + public static class DefaultComponentFactory implements ComponentFactory { + @Override + public Component createComponent(String fullyQualifiedClassName, + DesignContext context) { + Class<? extends Component> componentClass = resolveComponentClass( + fullyQualifiedClassName, context); + + assert Component.class.isAssignableFrom(componentClass) : "resolveComponentClass returned " + + componentClass + " which is not a Vaadin Component class"; + + try { + return componentClass.newInstance(); + } catch (Exception e) { + throw new DesignException("Could not create component " + + fullyQualifiedClassName, e); + } + } + + /** + * Resolves a component class based on the fully qualified name of the + * class. + * + * @param qualifiedClassName + * the fully qualified name of the resolved class + * @param context + * the design context for which the class is resolved + * @return a component class object representing the provided class name + */ + protected Class<? extends Component> resolveComponentClass( + String qualifiedClassName, DesignContext context) { + try { + Class<?> componentClass = Class.forName(qualifiedClassName); + return componentClass.asSubclass(Component.class); + } catch (ClassNotFoundException e) { + throw new DesignException( + "Unable to load component for design", e); + } + } + + } + + private static volatile ComponentFactory componentFactory = new DefaultComponentFactory(); + + /** + * Sets the component factory that is used for creating component instances + * based on fully qualified class names derived from a design file. + * <p> + * Please note that this setting is global, so care should be taken to avoid + * conflicting changes. + * + * @param componentFactory + * the component factory to set; not <code>null</code> + * + * @since 7.4.1 + */ + public static void setComponentFactory(ComponentFactory componentFactory) { + if (componentFactory == null) { + throw new IllegalArgumentException( + "Cannot set null component factory"); + } + Design.componentFactory = componentFactory; + } + + /** + * Gets the currently used component factory. + * + * @see #setComponentFactory(ComponentFactory) + * + * @return the component factory + * + * @since 7.4.1 + */ + public static ComponentFactory getComponentFactory() { + return componentFactory; + } + /** * Parses the given input stream into a jsoup document * diff --git a/server/src/com/vaadin/ui/declarative/DesignContext.java b/server/src/com/vaadin/ui/declarative/DesignContext.java index 5f160d6f26..09fefd0a6b 100644 --- a/server/src/com/vaadin/ui/declarative/DesignContext.java +++ b/server/src/com/vaadin/ui/declarative/DesignContext.java @@ -31,6 +31,7 @@ import com.vaadin.annotations.DesignRoot; import com.vaadin.shared.util.SharedUtil; import com.vaadin.ui.Component; import com.vaadin.ui.HasComponents; +import com.vaadin.ui.declarative.Design.ComponentFactory; /** * This class contains contextual information that is collected when a component @@ -482,14 +483,17 @@ public class DesignContext implements Serializable { private Component instantiateComponent(Node node) { // Extract the package and class names. String qualifiedClassName = tagNameToClassName(node); - try { - Class<? extends Component> componentClass = resolveComponentClass(qualifiedClassName); - Component newComponent = componentClass.newInstance(); - return newComponent; - } catch (Exception e) { - throw new DesignException("No component class could be found for " - + node.nodeName() + ".", e); + + ComponentFactory factory = Design.getComponentFactory(); + Component component = factory.createComponent(qualifiedClassName, this); + + if (component == null) { + throw new DesignException("Got unexpected null component from " + + factory.getClass().getName() + " for class " + + qualifiedClassName); } + + return component; } /** @@ -530,39 +534,6 @@ public class DesignContext implements Serializable { return packageName + "." + className; } - @SuppressWarnings("unchecked") - private Class<? extends Component> resolveComponentClass( - String qualifiedClassName) throws ClassNotFoundException { - Class<?> componentClass = null; - componentClass = Class.forName(qualifiedClassName); - - // Check that we're dealing with a Component. - if (isComponent(componentClass)) { - return (Class<? extends Component>) componentClass; - } else { - throw new IllegalArgumentException(String.format( - "Resolved class %s is not a %s.", componentClass.getName(), - Component.class.getName())); - } - } - - /** - * Returns {@code true} if the given {@link Class} implements the - * {@link Component} interface of Vaadin Framework otherwise {@code false}. - * - * @param componentClass - * {@link Class} to check against {@link Component} interface. - * @return {@code true} if the given {@link Class} is a {@link Component}, - * {@code false} otherwise. - */ - private static boolean isComponent(Class<?> componentClass) { - if (componentClass != null) { - return Component.class.isAssignableFrom(componentClass); - } else { - return false; - } - } - /** * Returns the root component of a created component hierarchy. * diff --git a/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java b/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java index 0518bea650..ccdbfea150 100644 --- a/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java +++ b/server/tests/src/com/vaadin/server/AbstractDeploymentConfigurationTest.java @@ -158,5 +158,9 @@ public class AbstractDeploymentConfigurationTest { return DefaultDeploymentConfiguration.DEFAULT_SEND_URLS_AS_PARAMETERS; } + @Override + public String getPushPath() { + return null; + } } } diff --git a/server/tests/src/com/vaadin/server/VaadinServiceTest.java b/server/tests/src/com/vaadin/server/VaadinServiceTest.java index 51325067d2..4b655e7855 100644 --- a/server/tests/src/com/vaadin/server/VaadinServiceTest.java +++ b/server/tests/src/com/vaadin/server/VaadinServiceTest.java @@ -15,6 +15,9 @@ */ package com.vaadin.server; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; + import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpSessionBindingEvent; @@ -39,6 +42,11 @@ public class VaadinServiceTest { } } + private String createCriticalNotification(String caption, String message, String details, String url) { + return VaadinService + .createCriticalNotificationJSON(caption, message, details, url); + } + @Test public void testFireSessionDestroy() throws ServletException { ServletConfig servletConfig = new MockServletConfig(); @@ -66,4 +74,68 @@ public class VaadinServiceTest { Assert.assertEquals("SessionDestroyListeners not called exactly once", 1, listener.callCount); } + + @Test + public void captionIsSetToACriticalNotification() { + String notification = + createCriticalNotification("foobar", "message", "details", "url"); + + assertThat(notification, containsString("\"caption\":\"foobar\"")); + } + + @Test + public void nullCaptionIsSetToACriticalNotification() { + String notification = + createCriticalNotification(null, "message", "details", "url"); + + assertThat(notification, containsString("\"caption\":null")); + } + + @Test + public void messageWithDetailsIsSetToACriticalNotification() { + String notification = + createCriticalNotification("caption", "foo", "bar", "url"); + + assertThat(notification, containsString("\"message\":\"foo<br/><br/>bar\"")); + } + + @Test + public void nullMessageIsReplacedByDetailsInACriticalNotification() { + String notification = + createCriticalNotification("caption", null, "foobar", "url"); + + assertThat(notification, containsString("\"message\":\"foobar\"")); + } + + @Test + public void nullMessageIsSetToACriticalNotification() { + String notification = + createCriticalNotification("caption", null, null, "url"); + + assertThat(notification, containsString("\"message\":null")); + } + + @Test + public void messageSetToACriticalNotification() { + String notification = + createCriticalNotification("caption", "foobar", null, "url"); + + assertThat(notification, containsString("\"message\":\"foobar\"")); + } + + @Test + public void urlIsSetToACriticalNotification() { + String notification = + createCriticalNotification("caption", "message", "details", "foobar"); + + assertThat(notification, containsString("\"url\":\"foobar\"")); + } + + @Test + public void nullUrlIsSetToACriticalNotification() { + String notification = + createCriticalNotification("caption", "message", "details", null); + + assertThat(notification, containsString("\"url\":null")); + } } diff --git a/server/tests/src/com/vaadin/tests/CompileTransitionPropertyTest.java b/server/tests/src/com/vaadin/tests/CompileTransitionPropertyTest.java new file mode 100644 index 0000000000..d6c564a42b --- /dev/null +++ b/server/tests/src/com/vaadin/tests/CompileTransitionPropertyTest.java @@ -0,0 +1,69 @@ +/* + * 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; + +import static org.junit.Assert.assertTrue; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; + +import com.vaadin.sass.internal.ScssStylesheet; + +/* + * This test checks that the transition mixin in valo/bourbon is usable (#15484). + */ +public class CompileTransitionPropertyTest { + + @Test + public void testCompilation() throws Exception { + ScssStylesheet ss = ScssStylesheet + .get("server/tests/src/com/vaadin/tests/styles.scss"); + ss.compile(); + // extract the style rules for .my-label + String compiled = ss.printState(); + Pattern pattern = Pattern.compile("(.my-label)(\\s)+(\\{)[^\\}]*"); + Matcher matcher = pattern.matcher(compiled); + assertTrue("Could not find style rules for .my-label.", matcher.find()); + String elementStyle = matcher.group(); + elementStyle = elementStyle.replaceFirst( + "(.my-label)(\\s)+(\\{)(\\s)*", ""); + // Check that the correct rules are present + Pattern p1 = Pattern + .compile("transition-property(\\s*):(\\s*)transform(\\s*);"); + Pattern p2 = Pattern + .compile("-moz-transition-property(\\s*):(\\s*)-moz-transform(\\s*);"); + Pattern p3 = Pattern + .compile("-webkit-transition-property(\\s*):(\\s*)-webkit-transform(\\s*);"); + assertTrue("The style 'transition-property: transform' is missing.", p1 + .matcher(elementStyle).find()); + assertTrue( + "The style '-moz-transition-property: -moz-transform' is missing.", + p2.matcher(elementStyle).find()); + assertTrue( + "The style '-webkit-transition-property: -webkit-transform' is missing.", + p3.matcher(elementStyle).find()); + // Check that there are no other styles for .my-label + String modifiedStyle = p1.matcher(elementStyle).replaceFirst(""); + modifiedStyle = p2.matcher(modifiedStyle).replaceFirst(""); + modifiedStyle = p3.matcher(modifiedStyle).replaceFirst(""); + // Only whitespace should remain after removing the style rules + modifiedStyle = modifiedStyle.replaceAll("(\\s)", ""); + assertTrue("Unexpected style rules for .my-label: " + modifiedStyle, + modifiedStyle.length() == 0); + } +}
\ No newline at end of file diff --git a/server/tests/src/com/vaadin/tests/design/ComponentFactoryTest.java b/server/tests/src/com/vaadin/tests/design/ComponentFactoryTest.java new file mode 100644 index 0000000000..a5f1d288a2 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/design/ComponentFactoryTest.java @@ -0,0 +1,117 @@ +/* + * 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.design; + +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.List; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.ui.Component; +import com.vaadin.ui.Label; +import com.vaadin.ui.declarative.Design; +import com.vaadin.ui.declarative.Design.ComponentFactory; +import com.vaadin.ui.declarative.DesignContext; +import com.vaadin.ui.declarative.DesignException; + +public class ComponentFactoryTest { + + private static final ComponentFactory defaultFactory = Design + .getComponentFactory(); + + private static final ThreadLocal<ComponentFactory> currentComponentFactory = new ThreadLocal<ComponentFactory>(); + + // Set static component factory that delegate to a thread local factory + static { + Design.setComponentFactory(new ComponentFactory() { + @Override + public Component createComponent(String fullyQualifiedClassName, + DesignContext context) { + ComponentFactory componentFactory = currentComponentFactory + .get(); + if (componentFactory == null) { + componentFactory = defaultFactory; + } + return componentFactory.createComponent( + fullyQualifiedClassName, context); + } + }); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetNullComponentFactory() { + Design.setComponentFactory(null); + } + + @Test + public void testComponentFactoryLogging() { + final List<String> messages = new ArrayList<String>(); + currentComponentFactory.set(new ComponentFactory() { + @Override + public Component createComponent(String fullyQualifiedClassName, + DesignContext context) { + messages.add("Requested class " + fullyQualifiedClassName); + return defaultFactory.createComponent(fullyQualifiedClassName, + context); + } + }); + + Design.read(new ByteArrayInputStream("<v-label />".getBytes())); + + Assert.assertEquals("There should be one message logged", 1, + messages.size()); + Assert.assertEquals( + "Requested class " + Label.class.getCanonicalName(), + messages.get(0)); + } + + @Test(expected = DesignException.class) + public void testComponentFactoryReturningNull() { + currentComponentFactory.set(new ComponentFactory() { + @Override + public Component createComponent(String fullyQualifiedClassName, + DesignContext context) { + return null; + } + }); + + Design.read(new ByteArrayInputStream("<v-label />".getBytes())); + } + + @Test(expected = DesignException.class) + public void testComponentFactoryThrowingStuff() { + currentComponentFactory.set(new ComponentFactory() { + @Override + public Component createComponent(String fullyQualifiedClassName, + DesignContext context) { + // Will throw because class is not found + return defaultFactory.createComponent("foobar." + + fullyQualifiedClassName, context); + } + }); + + Design.read(new ByteArrayInputStream("<v-label />".getBytes())); + } + + @After + public void cleanup() { + currentComponentFactory.remove(); + } + +} diff --git a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java index 06c1b14bb6..fda662e4d9 100644 --- a/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java +++ b/server/tests/src/com/vaadin/tests/server/component/grid/GridColumns.java @@ -185,6 +185,25 @@ public class GridColumns { } @Test + public void testSetFrozenColumnCount() { + assertEquals("Grid should not start with a frozen column", 0, + grid.getFrozenColumnCount()); + grid.setFrozenColumnCount(2); + assertEquals("Freezing two columns should freeze two columns", 2, + grid.getFrozenColumnCount()); + } + + @Test + public void testSetFrozenColumnCountThroughColumn() { + assertEquals("Grid should not start with a frozen column", 0, + grid.getFrozenColumnCount()); + grid.getColumns().get(2).setLastFrozenColumn(); + assertEquals( + "Setting the third column as last frozen should freeze three columns", + 3, grid.getFrozenColumnCount()); + } + + @Test public void testFrozenColumnRemoveColumn() { assertEquals("Grid should not start with a frozen column", 0, grid.getFrozenColumnCount()); diff --git a/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java b/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java index f568da1392..48bba8a853 100644 --- a/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java +++ b/server/tests/src/com/vaadin/tests/server/component/slider/SliderTest.java @@ -1,24 +1,68 @@ package com.vaadin.tests.server.component.slider; -import junit.framework.TestCase; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; import org.junit.Assert; +import org.junit.Test; import com.vaadin.ui.Slider; -import com.vaadin.ui.Slider.ValueOutOfBoundsException; -public class SliderTest extends TestCase { +public class SliderTest { - public void testOutOfBounds() { + @Test + public void minCannotBeLargerThanMax() { + Slider slider = new Slider(); + + slider.setMax(100); + slider.setMin(101); + + assertThat(slider.getMin(), is(101.0)); + assertThat(slider.getMax(), is(101.0)); + } + + @Test + public void maxCannotBeSmallerThanMin() { + Slider slider = new Slider(); + + slider.setMin(50); + slider.setMax(10); + + assertThat(slider.getMax(), is(10.0)); + assertThat(slider.getMin(), is(10.0)); + } + + @Test + public void valueOutOfBoundsExceptionMessageContainsBounds() { + Slider slider = new Slider(); + + try { + + slider.setValue(-1.0); + } catch (Slider.ValueOutOfBoundsException e) { + assertThat(e.getMessage(), + containsString("Value -1.0 is out of bounds: [0.0, 100.0]")); + } + } + + @Test + public void valueIsSet() { + Slider slider = new Slider(); + + slider.setValue(5.0); + + assertThat(slider.getValue(), is(5.0)); + } + + @Test + public void valueCannotBeOutOfBounds() { Slider s = new Slider(0, 10); - s.setValue(0.0); - Assert.assertEquals(0.0, s.getValue().doubleValue(), 0.001); - s.setValue(10.0); - Assert.assertEquals(10.0, s.getValue().doubleValue(), 0.001); + try { s.setValue(20.0); - fail("Should throw out of bounds exception"); - } catch (ValueOutOfBoundsException e) { + Assert.fail("Should throw out of bounds exception"); + } catch (Slider.ValueOutOfBoundsException e) { // TODO: handle exception } diff --git a/server/tests/src/com/vaadin/tests/styles.scss b/server/tests/src/com/vaadin/tests/styles.scss new file mode 100644 index 0000000000..d574243969 --- /dev/null +++ b/server/tests/src/com/vaadin/tests/styles.scss @@ -0,0 +1,5 @@ +@import "../../../../../../WebContent/VAADIN/themes/valo/valo"; + +.my-label { + @include transition-property (transform); +}
\ No newline at end of file diff --git a/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java b/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java index ddee23a9ec..175dcb2b94 100644 --- a/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java +++ b/server/tests/src/com/vaadin/tests/util/MockDeploymentConfiguration.java @@ -22,6 +22,7 @@ public class MockDeploymentConfiguration extends private LegacyProperyToStringMode legacyPropertyToStringMode = LegacyProperyToStringMode.DISABLED; private boolean syncIdCheckEnabled = true; private boolean sendUrlsAsParameters = true; + private String pushPath = "PUSH"; @Override public boolean isProductionMode() { @@ -125,4 +126,9 @@ public class MockDeploymentConfiguration extends return sendUrlsAsParameters; } + @Override + public String getPushPath() { + return pushPath; + } + } diff --git a/shared/build.xml b/shared/build.xml index a9cd0b9803..30f4ac65ce 100644 --- a/shared/build.xml +++ b/shared/build.xml @@ -3,8 +3,7 @@ <project name="vaadin-shared" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant"> <description> - Compiles build helpers used when building other - modules. + The shared module containing classes used by both server and client. </description> <include file="../common.xml" as="common" /> <include file="../build.xml" as="vaadin" /> @@ -23,7 +22,9 @@ <target name="jar"> <property name="shared.osgi.import" - value="com.google.gwt.thirdparty.guava.common.annotations;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.base;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.base.internal;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.cache;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.collect;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.eventbus;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.io;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.net;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.primitives;version="16.0.1.vaadin1", com.google.gwt.thirdparty.guava.common.util.concurrent;version="16.0.1.vaadin1", com.google.gwt.thirdparty.streamhtmlparser;version="0.0.10.vaadin1", com.google.gwt.thirdparty.streamhtmlparser.impl;version="0.0.10.vaadin1", com.google.gwt.thirdparty.streamhtmlparser.util;version="0.0.10.vaadin1", org.w3c.flute.parser;version="1.3.0.gg2", org.w3c.flute.parser.selectors;version="1.3.0.gg2", org.w3c.flute.util;version="1.3.0.gg2"" /> + value="com.google.gwt.thirdparty.streamhtmlparser;version="0.0.10.vaadin1", com.google.gwt.thirdparty.streamhtmlparser.impl;version="0.0.10.vaadin1", com.google.gwt.thirdparty.streamhtmlparser.util;version="0.0.10.vaadin1", org.w3c.flute.parser;version="1.3.0.gg2", org.w3c.flute.parser.selectors;version="1.3.0.gg2", org.w3c.flute.util;version="1.3.0.gg2"" /> + <property name="shared.osgi.require-bundle" + value="com.google.gwt.thirdparty.guava;bundle-version="16.0.1.vaadin1"" /> <delete dir="${src.filtered}" /> <!-- Update version in Version.java --> <copy todir="${src.filtered}"> @@ -38,6 +39,7 @@ <antcall target="common.jar"> <param name="import-package" value="${shared.osgi.import}" /> + <param name="require-bundle" value="${shared.osgi.require-bundle}" /> <reference refid="shared.gwt.includes" torefid="extra.jar.includes" /> <param name="osgi.extra.package.prefixes" value="elemental" /> </antcall> diff --git a/shared/src/com/vaadin/shared/ApplicationConstants.java b/shared/src/com/vaadin/shared/ApplicationConstants.java index d7aaee6267..990564a6b8 100644 --- a/shared/src/com/vaadin/shared/ApplicationConstants.java +++ b/shared/src/com/vaadin/shared/ApplicationConstants.java @@ -28,8 +28,6 @@ public class ApplicationConstants implements Serializable { public static final String HEARTBEAT_PATH = "HEARTBEAT"; - public static final String PUSH_PATH = "PUSH"; - public static final String PUBLISHED_FILE_PATH = APP_PATH + '/' + "PUBLISHED"; @@ -76,7 +74,7 @@ public class ApplicationConstants implements Serializable { /** * The name of the javascript containing the bootstrap code. The file is * located in the VAADIN directory. - * + * * @since 7.3 */ public static final String VAADIN_BOOTSTRAP_JS = "vaadinBootstrap.js"; @@ -90,7 +88,7 @@ public class ApplicationConstants implements Serializable { /** * The name of the debug version of the javascript containing push support. * The file is located in the VAADIN directory. - * + * * @since 7.1.6 */ public static final String VAADIN_PUSH_DEBUG_JS = "vaadinPush.debug.js"; @@ -102,14 +100,14 @@ public class ApplicationConstants implements Serializable { /** * The name of the parameter used to transmit RPC invocations - * + * * @since 7.2 */ public static final String RPC_INVOCATIONS = "rpc"; /** * The name of the parameter used to transmit the CSRF token - * + * * @since 7.2 */ public static final String CSRF_TOKEN = "csrfToken"; @@ -118,7 +116,7 @@ public class ApplicationConstants implements Serializable { * The name of the parameter used to transmit the sync id. The value can be * set to -1 e.g. when testing with pre-recorded requests to make the * framework ignore the sync id. - * + * * @see com.vaadin.ui.ConnectorTracker#getCurrentSyncId() * @since 7.2 */ diff --git a/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java b/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java index ed849cb361..4ba081b5df 100644 --- a/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java +++ b/shared/src/com/vaadin/shared/ui/grid/GridClientRpc.java @@ -50,4 +50,9 @@ public interface GridClientRpc extends ClientRpc { */ public void scrollToEnd(); + /** + * Command client Grid to recalculate column widths. + */ + public void recalculateColumnWidths(); + } diff --git a/shared/src/com/vaadin/shared/ui/ui/UIState.java b/shared/src/com/vaadin/shared/ui/ui/UIState.java index 2f51fef6ee..04e182c5d4 100644 --- a/shared/src/com/vaadin/shared/ui/ui/UIState.java +++ b/shared/src/com/vaadin/shared/ui/ui/UIState.java @@ -110,6 +110,7 @@ public class UIState extends TabIndexState { public static final String FALLBACK_TRANSPORT_PARAM = "fallbackTransport"; public PushMode mode = PushMode.DISABLED; + public String pushPath; public Map<String, String> parameters = new HashMap<String, String>(); { parameters diff --git a/uitest/integration_tests.xml b/uitest/integration_tests.xml index 4469b58c24..26ce4ed70d 100644 --- a/uitest/integration_tests.xml +++ b/uitest/integration_tests.xml @@ -27,6 +27,8 @@ <!-- 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" /> @@ -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 78171f9a9c..9c4db1584b 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" @@ -28,7 +28,7 @@ <dependency org="javax.validation" name="validation-api" rev="1.0.0.GA" conf="build,ide -> default,sources" /> <dependency org="org.hibernate" name="hibernate-validator" - rev="4.2.0.Final" conf="build,ide -> default" /> + rev="4.2.0.Final" conf="build,ide -> default" /> <!-- Google App Engine --> <dependency org="com.google.appengine" name="appengine-api-1.0-sdk" rev="1.2.1" conf="build-provided,ide -> default" /> @@ -74,11 +74,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> @@ -86,31 +92,33 @@ <dependency org="junit" name="junit" rev="4.11" conf="build,ide -> default" /> - <dependency org="org.hamcrest" name="hamcrest-all" rev="1.3" - conf="build,ide->default" /> + <dependency org="org.hamcrest" name="hamcrest-all" + rev="1.3" conf="build,ide->default" /> <dependency org="com.jcraft" name="jsch" rev="0.1.50" conf="ide, build->default" /> <dependency org="commons-codec" name="commons-codec" rev="1.5" conf="build,ide->default" /> - <dependency org="commons-io" name="commons-io" rev="${commons-io.version}" - conf="build,ide->default" /> + <dependency org="commons-io" name="commons-io" + rev="${commons-io.version}" conf="build,ide->default" /> <!-- Mainly for SQLContainer tests --> <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" /> - <dependency org="com.vaadin" name="vaadin-sass-compiler" + <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" /> + 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" /> + <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> diff --git a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java index e2b93ab7d2..5c2e58d3a2 100644 --- a/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java +++ b/uitest/src/com/vaadin/launcher/ApplicationRunnerServlet.java @@ -402,9 +402,12 @@ public class ApplicationRunnerServlet extends LegacyVaadinServlet { try { VaadinServletService service = (VaadinServletService) VaadinService .getCurrent(); - session = service - .findVaadinSession(new VaadinServletRequest( - currentRequest, service)); + if (service != null) { + session = service + .findVaadinSession(new VaadinServletRequest( + currentRequest, service)); + } + } finally { /* * Clear some state set by findVaadinSession to diff --git a/uitest/src/com/vaadin/testbench/elements/GridElement.java b/uitest/src/com/vaadin/testbench/elements/GridElement.java index 3753696855..68ddfc878e 100644 --- a/uitest/src/com/vaadin/testbench/elements/GridElement.java +++ b/uitest/src/com/vaadin/testbench/elements/GridElement.java @@ -23,6 +23,8 @@ import org.openqa.selenium.WebElement; import com.vaadin.testbench.By; import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elementsbase.AbstractElement; +import com.vaadin.testbench.elementsbase.ServerClass; /** * TestBench Element API for Grid diff --git a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java index 38c94dda7d..5b4f4df788 100644 --- a/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java +++ b/uitest/src/com/vaadin/tests/VerifyBrowserVersionTest.java @@ -19,28 +19,14 @@ import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import java.util.HashMap; -import java.util.Map; - import org.junit.Test; import org.openqa.selenium.remote.DesiredCapabilities; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class VerifyBrowserVersionTest extends MultiBrowserTest { - private Map<DesiredCapabilities, String> expectedUserAgent = new HashMap<DesiredCapabilities, String>(); - - { - expectedUserAgent.put(Browser.FIREFOX.getDesiredCapabilities(), "Firefox/"); - expectedUserAgent.put(Browser.IE8.getDesiredCapabilities(), "MSIE "); - expectedUserAgent.put(Browser.IE9.getDesiredCapabilities(), "MSIE "); - expectedUserAgent.put(Browser.IE10.getDesiredCapabilities(), "MSIE "); - expectedUserAgent.put(Browser.IE11.getDesiredCapabilities(), "Trident/7.0; rv:"); - expectedUserAgent.put(Browser.CHROME.getDesiredCapabilities(), "Chrome/"); - expectedUserAgent.put(Browser.PHANTOMJS.getDesiredCapabilities(), "PhantomJS/"); - } - @Test public void verifyUserAgent() { openTestURL(); @@ -48,11 +34,31 @@ public class VerifyBrowserVersionTest extends MultiBrowserTest { DesiredCapabilities desiredCapabilities = getDesiredCapabilities(); assertThat(vaadinElementById("userAgent").getText(), - containsString(expectedUserAgent.get(desiredCapabilities) - + desiredCapabilities.getVersion())); + containsString(getExpectedUserAgentString(desiredCapabilities) + + desiredCapabilities.getVersion())); assertThat(vaadinElementById("touchDevice").getText(), - is("Touch device? No")); + is("Touch device? No")); + } + + private String getExpectedUserAgentString(DesiredCapabilities dCap) { + if (BrowserUtil.isIE(dCap)) { + if (!BrowserUtil.isIE(dCap, 11)) { + // IE8-10 + return "MSIE "; + } else { + // IE11 + return "Trident/7.0; rv:"; + } + } else if (BrowserUtil.isFirefox(dCap)) { + return "Firefox/"; + } else if (BrowserUtil.isChrome(dCap)) { + return "Chrome/"; + } else if (BrowserUtil.isPhantomJS(dCap)) { + return "PhantomJS/"; + } + throw new UnsupportedOperationException( + "Test is being run on unknown browser."); } } diff --git a/uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java b/uitest/src/com/vaadin/tests/actions/ActionsOnInvisibleComponentsTest.java index 8dfcf52b75..1231b0036e 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 { @@ -15,12 +16,8 @@ public class ActionsOnInvisibleComponentsTest extends MultiBrowserTest { // This method should be removed once #12785 is fixed @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - // Send Keys does not function correctly on these browsers. - browsers.remove(Browser.CHROME.getDesiredCapabilities()); - browsers.remove(Browser.FIREFOX.getDesiredCapabilities()); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - return browsers; + return getBrowserCapabilities(Browser.IE9, Browser.IE10, Browser.IE11, + Browser.PHANTOMJS); } @Test diff --git a/uitest/src/com/vaadin/tests/annotations/TestCategory.java b/uitest/src/com/vaadin/tests/annotations/TestCategory.java deleted file mode 100644 index 5ba6cc3faa..0000000000 --- a/uitest/src/com/vaadin/tests/annotations/TestCategory.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Inherited -public @interface TestCategory { - - String value(); - -} diff --git a/uitest/src/com/vaadin/tests/application/DeploymentConfiguration.java b/uitest/src/com/vaadin/tests/application/DeploymentConfiguration.java new file mode 100644 index 0000000000..9c95479bec --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/DeploymentConfiguration.java @@ -0,0 +1,27 @@ +package com.vaadin.tests.application; + +import java.util.Properties; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.MarginInfo; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; + +public class DeploymentConfiguration extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Properties params = getSession().getConfiguration().getInitParameters(); + getLayout().setMargin(new MarginInfo(true, false, false, false)); + + for (Object key : params.keySet()) { + addComponent(new Label(key + ": " + + params.getProperty((String) key))); + } + } + + @Override + protected String getTestDescription() { + return "Init parameters:"; + } +} diff --git a/uitest/src/com/vaadin/tests/application/DeploymentConfigurationTest.java b/uitest/src/com/vaadin/tests/application/DeploymentConfigurationTest.java index 799622b31d..9a51980c9e 100644 --- a/uitest/src/com/vaadin/tests/application/DeploymentConfigurationTest.java +++ b/uitest/src/com/vaadin/tests/application/DeploymentConfigurationTest.java @@ -1,25 +1,48 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ package com.vaadin.tests.application; -import java.util.Properties; +import static org.junit.Assert.assertTrue; -import com.vaadin.server.VaadinRequest; -import com.vaadin.ui.Label; -import com.vaadin.ui.UI; -import com.vaadin.ui.VerticalLayout; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; -public class DeploymentConfigurationTest extends UI { +import org.junit.Test; - @Override - protected void init(VaadinRequest request) { - VerticalLayout layout = new VerticalLayout(); - layout.setMargin(true); - setContent(layout); +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; - Properties params = getSession().getConfiguration().getInitParameters(); +public class DeploymentConfigurationTest extends MultiBrowserTest { - for (Object key : params.keySet()) { - layout.addComponent(new Label(key + ": " - + params.getProperty((String) key))); + @Test + public void testParameters() { + openTestURL(); + List<String> texts = new ArrayList<String>(Arrays.asList( + "Init parameters:", "legacyPropertyToString: false", + "closeIdleSessions: true", "productionMode: false", + "testParam: 42", "heartbeatInterval: 301", + "resourceCacheTime: 3601")); + + for (LabelElement label : $(LabelElement.class).all()) { + assertTrue(label.getText() + " not found", + texts.contains(label.getText())); + texts.remove(label.getText()); } + assertTrue(texts.isEmpty()); } + } diff --git a/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java index 8cb670c0fb..a7c9239fae 100644 --- a/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java +++ b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReload.java @@ -50,6 +50,7 @@ public class DetachOldUIOnReload extends AbstractTestUIWithLog { } private List<String> getSessionMessages(boolean storeIfNeeded) { + @SuppressWarnings("unchecked") List<String> messages = (List<String>) getSession().getAttribute( PERSISTENT_MESSAGES_ATTRIBUTE); if (messages == null) { diff --git a/uitest/src/com/vaadin/tests/application/DetachOldUIOnReloadTest.java b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReloadTest.java new file mode 100644 index 0000000000..1e156c3e46 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/DetachOldUIOnReloadTest.java @@ -0,0 +1,85 @@ +/* + * 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.application; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DetachOldUIOnReloadTest extends MultiBrowserTest { + + private static final String RELOAD = "Reload page"; + private static final String READ_LOG = "Read log messages from session"; + + @Test + public void testDetachesUIOnReload() throws InterruptedException { + openTestURL(); + List<LabelElement> labels = $(LabelElement.class).all(); + assertEquals("initial label incorrect", "This is UI 0", + lastLabelText(labels)); + + assertFalse("reloading button not found", $(ButtonElement.class) + .caption(RELOAD).all().isEmpty()); + + openTestURL(); + click(READ_LOG); + + checkLabels("first", 1); + + click(RELOAD); + click(READ_LOG); + + checkLabels("second", 2); + + openTestURL(); + click(READ_LOG); + + checkLabels("third", 3); + + // restarting reverts to 0 + openTestURL("restartApplication"); + + checkLabels("final", 0); + } + + private void checkLabels(String descriptor, int index) { + List<LabelElement> labels = $(LabelElement.class).all(); + assertEquals( + String.format("label incorrect after %s reload", descriptor), + String.format("This is UI %s", index), lastLabelText(labels)); + if (!"final".equals(descriptor)) { + assertEquals(String.format("log message incorrect after %s reload", + descriptor), String.format("%s. UI %s has been detached", + index, index - 1), labels.get(0).getText()); + } + } + + private String lastLabelText(List<LabelElement> labels) { + return labels.get(labels.size() - 1).getText(); + } + + private void click(String caption) { + $(ButtonElement.class).caption(caption).first().click(); + } + +} diff --git a/uitest/src/com/vaadin/tests/application/ErrorInUnloadEventTest.java b/uitest/src/com/vaadin/tests/application/ErrorInUnloadEventTest.java new file mode 100644 index 0000000000..fa316c6749 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/ErrorInUnloadEventTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.application; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.PasswordFieldElement; +import com.vaadin.testbench.elements.TextFieldElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ErrorInUnloadEventTest extends MultiBrowserTest { + + @Test + public void testError() { + openTestURL(); + TextFieldElement user = $(TextFieldElement.class).id("user"); + user.focus(); + user.sendKeys("a"); + PasswordFieldElement pass = $(PasswordFieldElement.class).id("pwd"); + pass.focus(); + pass.sendKeys("d"); + ButtonElement button = $(ButtonElement.class).id("loginButton"); + button.click(); + + assertEquals("label is incorrect, error while loading page", + "...Title...", $(LabelElement.class).first().getText()); + + openTestURL(); + // no errors and page fully reloaded + assertTrue($(LabelElement.class).all().isEmpty()); + } + +} diff --git a/uitest/src/com/vaadin/tests/application/VaadinSessionAttributeTest.java b/uitest/src/com/vaadin/tests/application/VaadinSessionAttributeTest.java new file mode 100644 index 0000000000..47e86d9039 --- /dev/null +++ b/uitest/src/com/vaadin/tests/application/VaadinSessionAttributeTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.application; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.FixedNotificationElement; + +public class VaadinSessionAttributeTest extends MultiBrowserTest { + + @Test + public void testSessionAttribute() { + openTestURL(); + $(ButtonElement.class).first().click(); + assertEquals("notification does not contain suitable text", "42 & 84", + $(FixedNotificationElement.class).first().getCaption()); + } + +} diff --git a/uitest/src/com/vaadin/tests/applicationcontext/CleanupBrokenUI.java b/uitest/src/com/vaadin/tests/applicationcontext/CleanupBrokenUI.java new file mode 100644 index 0000000000..4af4f23bfa --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationcontext/CleanupBrokenUI.java @@ -0,0 +1,65 @@ +/* + * 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.applicationcontext; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Label; + +/** + * Tests that UI is cleaned from session despite any errors that happen in + * detach. + * + * @author Vaadin Ltd + */ +public class CleanupBrokenUI extends AbstractTestUIWithLog { + + @Override + protected void setup(VaadinRequest request) { + logUIs(); + addComponent(new Label("Label with broken detach") { + @Override + public void detach() { + throw new IllegalStateException( + "Detach does not work for this component"); + } + }); + + addComponent(new Button("Ping", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + log("pong"); + } + })); + + } + + private void logUIs() { + log("UIs in session: " + getSession().getUIs().size()); + } + + @Override + protected String getTestDescription() { + return "Open the page as http://localhost:8888/run/CleanupBrokenUI, then refresh the page to get a new UI. On refresh there should be an IllegalStateException in the server log but pressing 'ping' after this should log no further messages and the old ui should no longer be in the VaadinSession"; + } + + @Override + protected Integer getTicketNumber() { + return 16651; + } +} diff --git a/uitest/src/com/vaadin/tests/applicationcontext/CleanupBrokenUITest.java b/uitest/src/com/vaadin/tests/applicationcontext/CleanupBrokenUITest.java new file mode 100644 index 0000000000..404e05eefc --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationcontext/CleanupBrokenUITest.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.applicationcontext; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class CleanupBrokenUITest extends SingleBrowserTest { + + @Test + public void ensureUIDetached() { + openTestURL(); + // UI 1 has not yet been added in UI.init where logging takes place + Assert.assertEquals("1. UIs in session: 0", getLogRow(0)); + + String url = getTestURL(getUIClass()) + .replace("restartApplication", "1"); + driver.get(url); + // UI 1 remains in session during UI2 init where logging takes place + Assert.assertEquals("1. UIs in session: 1", getLogRow(0)); + + // At this point UI1 should be removed from the session + driver.get(url); + + // UI 2 remains in session during UI3 init where logging takes place + // UI 1 should have been removed + Assert.assertEquals("1. UIs in session: 1", getLogRow(0)); + } +} diff --git a/uitest/src/com/vaadin/tests/applicationservlet/MultipleServletConfigurationTest.java b/uitest/src/com/vaadin/tests/applicationservlet/MultipleServletConfigurationTest.java new file mode 100644 index 0000000000..39e8d04ffc --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationservlet/MultipleServletConfigurationTest.java @@ -0,0 +1,29 @@ +package com.vaadin.tests.applicationservlet; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class MultipleServletConfigurationTest extends MultiBrowserTest { + + @Override + protected void closeApplication() { + } + + @Test + public void testMultipleServletConfiguration() throws Exception { + getDriver().get(getBaseURL() + "/embed1"); + assertLabelText("A generic test for Buttons in different configurations"); + getDriver().get(getBaseURL() + "/embed2"); + assertLabelText("Margins inside labels should not be allowed to collapse out of the label as it causes problems with layotus measuring the label."); + getDriver().get(getBaseURL() + "/embed1"); + assertLabelText("A generic test for Buttons in different configurations"); + } + + private void assertLabelText(String expected) { + Assert.assertEquals("Unexpected label text,", expected, + $(LabelElement.class).first().getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java index 5a815fb40c..3faf5bde72 100644 --- a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java +++ b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java @@ -15,35 +15,34 @@ */ package com.vaadin.tests.applicationservlet; -import java.util.Collections; -import java.util.List; - import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.By; -import org.openqa.selenium.remote.DesiredCapabilities; -import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.SingleBrowserTest; -public class NoApplicationClassTest extends MultiBrowserTest { +public class NoApplicationClassTest extends SingleBrowserTest { @Test public void testInvalidApplicationClass() { openTestURL(); String exceptionMessage = getDriver().findElement(By.xpath("//pre[2]")) .getText(); - Assert.assertTrue(exceptionMessage - .contains("ServletException: java.lang.ClassNotFoundException: ClassThatIsNotPresent")); + String expected = "ServletException: java.lang.ClassNotFoundException: ClassThatIsNotPresent"; + Assert.assertTrue( + String.format( + "Unexpected error message.\n expected to contain: '%s'\n was: %s", + expected, exceptionMessage), exceptionMessage + .contains(expected)); } @Override - public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.singletonList(Browser.CHROME - .getDesiredCapabilities()); + protected String getDeploymentPath() { + return "/run/ClassThatIsNotPresent"; } @Override - protected String getDeploymentPath() { - return "/run/ClassThatIsNotPresent"; + protected void openTestURL(String... parameters) { + driver.get(getTestUrl()); } } diff --git a/uitest/src/com/vaadin/tests/applicationservlet/SystemMessages.java b/uitest/src/com/vaadin/tests/applicationservlet/SystemMessages.java new file mode 100644 index 0000000000..00547aa2d2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/applicationservlet/SystemMessages.java @@ -0,0 +1,81 @@ +package com.vaadin.tests.applicationservlet; + +import java.util.Locale; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.launcher.ApplicationRunnerServlet; +import com.vaadin.server.CustomizedSystemMessages; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinService; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.NativeSelect; + +public class SystemMessages extends AbstractTestUI { + + public class MyButton extends Button { + private boolean fail = false; + + @Override + public void beforeClientResponse(boolean initial) { + // Set the error message to contain the current locale. + VaadinService.getCurrentRequest().setAttribute( + ApplicationRunnerServlet.CUSTOM_SYSTEM_MESSAGES_PROPERTY, + new CustomizedSystemMessages() { + @Override + public String getInternalErrorMessage() { + return "MessagesInfo locale: " + getLocale(); + } + }); + super.beforeClientResponse(initial); + if (fail) { + throw new RuntimeException("Failed on purpose"); + } + } + } + + @Override + protected void setup(final VaadinRequest request) { + final NativeSelect localeSelect = new NativeSelect("UI locale"); + localeSelect.setImmediate(true); + localeSelect.addItem(new Locale("en", "US")); + localeSelect.addItem(new Locale("fi", "FI")); + localeSelect.addItem(Locale.GERMANY); + localeSelect.addValueChangeListener(new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + Locale locale = (Locale) localeSelect.getValue(); + setLocale(locale); + } + }); + localeSelect.setValue(new Locale("fi", "FI")); + addComponent(localeSelect); + final MyButton failButton = new MyButton(); + failButton.setCaption("Generate server side error"); + failButton.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + failButton.fail = true; + failButton.markAsDirty(); + } + }); + addComponent(failButton); + + } + + @Override + protected String getTestDescription() { + return "SystemMessagesProvider.getSystemMessages should get an event object"; + } + + @Override + protected Integer getTicketNumber() { + return 10226; + } + +} diff --git a/uitest/src/com/vaadin/tests/applicationservlet/SystemMessagesTest.java b/uitest/src/com/vaadin/tests/applicationservlet/SystemMessagesTest.java index 047e465722..bbbb49b39c 100644 --- a/uitest/src/com/vaadin/tests/applicationservlet/SystemMessagesTest.java +++ b/uitest/src/com/vaadin/tests/applicationservlet/SystemMessagesTest.java @@ -1,91 +1,34 @@ package com.vaadin.tests.applicationservlet; -import java.util.Locale; +import org.junit.Assert; +import org.junit.Test; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.server.CustomizedSystemMessages; -import com.vaadin.server.SystemMessages; -import com.vaadin.server.SystemMessagesInfo; -import com.vaadin.server.SystemMessagesProvider; -import com.vaadin.server.VaadinRequest; -import com.vaadin.tests.components.AbstractTestUI; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Button.ClickListener; -import com.vaadin.ui.NativeSelect; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.tb3.MultiBrowserTest; -public class SystemMessagesTest extends AbstractTestUI { - - public class MyButton extends Button { - private boolean fail = false; - - @Override - public void beforeClientResponse(boolean initial) { - super.beforeClientResponse(initial); - if (fail) { - throw new RuntimeException("Failed on purpose"); - } - } - - } - - @Override - protected void setup(VaadinRequest request) { - final NativeSelect localeSelect = new NativeSelect("UI locale"); - localeSelect.setImmediate(true); - localeSelect.addItem(new Locale("en", "US")); - localeSelect.addItem(new Locale("fi", "FI")); - localeSelect.addItem(Locale.GERMANY); - localeSelect.addValueChangeListener(new ValueChangeListener() { - - @Override - public void valueChange(ValueChangeEvent event) { - setLocale((Locale) localeSelect.getValue()); - getSession().getService().setSystemMessagesProvider( - new SystemMessagesProvider() { - - @Override - public SystemMessages getSystemMessages( - SystemMessagesInfo systemMessagesInfo) { - CustomizedSystemMessages csm = new CustomizedSystemMessages(); - // csm.setInternalErrorCaption("Request query string: " - // + ((VaadinServletRequest) systemMessagesInfo - // .getRequest()).getQueryString()); - csm.setInternalErrorMessage("MessagesInfo locale: " - + systemMessagesInfo.getLocale()); - return csm; - - } - }); - } - }); - localeSelect.setValue(new Locale("fi", "FI")); - addComponent(localeSelect); - final MyButton failButton = new MyButton(); - failButton.setCaption("Generate server side error"); - failButton.addClickListener(new ClickListener() { - - @Override - public void buttonClick(ClickEvent event) { - failButton.fail = true; - failButton.markAsDirty(); - } - }); - addComponent(failButton); +public class SystemMessagesTest extends MultiBrowserTest { + @Test + public void testFinnishLocaleInSystemErrorMessage() throws Exception { + openTestURL(); + verifyError("fi_FI"); } - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; + @Test + public void testGermanLocaleInSystemErrorMessage() throws Exception { + openTestURL(); + $(NativeSelectElement.class).first().selectByText("de_DE"); + verifyError("de_DE"); } - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; + private void verifyError(String locale) { + $(ButtonElement.class).first().click(); + NotificationElement notification = $(NotificationElement.class).first(); + Assert.assertEquals("Incorrect notification caption,", + notification.getCaption(), "Internal error"); + Assert.assertEquals("Incorrect notification description,", + notification.getDescription(), "MessagesInfo locale: " + locale); } - } diff --git a/uitest/src/com/vaadin/tests/applicationservlet/UIProviderInitParameterTest.java b/uitest/src/com/vaadin/tests/applicationservlet/UIProviderInitParameterTest.java index 8197bbe8b8..7f9a375440 100644 --- a/uitest/src/com/vaadin/tests/applicationservlet/UIProviderInitParameterTest.java +++ b/uitest/src/com/vaadin/tests/applicationservlet/UIProviderInitParameterTest.java @@ -27,6 +27,16 @@ import com.vaadin.tests.tb3.MultiBrowserTest; public class UIProviderInitParameterTest extends MultiBrowserTest { + @Override + protected void openTestURL(String... parameters) { + driver.get(getTestUrl()); + } + + @Override + protected String getDeploymentPath() { + return "/uiprovider"; + } + @Test public void testDefault() { // Test that UI parameter is used by default @@ -50,9 +60,4 @@ public class UIProviderInitParameterTest extends MultiBrowserTest { assertEquals("unexpected text found", message, label.getText()); } - @Override - protected String getDeploymentPath() { - return "/uiprovider"; - } - } diff --git a/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java b/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java index 4f5c16218e..69e4aaa06c 100644 --- a/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java +++ b/uitest/src/com/vaadin/tests/components/AbstractOrderedLayoutWithCaptionsTest.java @@ -25,6 +25,7 @@ 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; /** diff --git a/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java b/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java index bf84695c3b..a43db58fd0 100644 --- a/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java +++ b/uitest/src/com/vaadin/tests/components/SaneErrorsTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.components; -import java.util.Collections; import java.util.List; import org.junit.Assert; @@ -24,6 +23,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; public class SaneErrorsTest extends MultiBrowserTest { @@ -35,7 +35,7 @@ public class SaneErrorsTest extends MultiBrowserTest { */ @Override public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.singletonList(DesiredCapabilities.firefox()); + return getBrowserCapabilities(Browser.FIREFOX); } @Test diff --git a/uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java b/uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java new file mode 100644 index 0000000000..1a3b4cdda5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java @@ -0,0 +1,57 @@ +package com.vaadin.tests.components; + +import com.vaadin.data.util.converter.StringToIntegerConverter; +import com.vaadin.data.validator.IntegerRangeValidator; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; + +public class TouchDevicesTooltip extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Label errorLabel = new Label("No error"); + addComponent(errorLabel); + + TextField textField = new TextField("Value"); + textField.setConverter(new StringToIntegerConverter()); + textField.addValidator(new IntegerRangeValidator("incorrect value", 0, 100)); + textField.setImmediate(true); + textField.setValue("-5"); + addComponent(textField); + + TextField textField2 = new TextField("Value2"); + textField2.setConverter(new StringToIntegerConverter()); + textField2.addValidator(new IntegerRangeValidator("incorrect value2", 0, 100)); + textField2.setImmediate(true); + textField2.setValue("-5"); + addComponent(textField2); + } + + public static class Bean { + @NotNull + @Min(0) + private Integer value; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + } + + @Override + protected Integer getTicketNumber() { + return 15353; + } + + @Override + public String getDescription() { + return "Displaying error message in slot for touch devices"; + } +} diff --git a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java index 0ec196f266..740d451b0f 100644 --- a/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java +++ b/uitest/src/com/vaadin/tests/components/calendar/BeanItemContainerLongEventTest.java @@ -32,6 +32,11 @@ public class BeanItemContainerLongEventTest extends MultiBrowserTest { return "/run/BeanItemContainerTestUI?restartApplication"; } + @Override + protected void openTestURL(String... parameters) { + driver.get(getTestUrl()); + } + @Test public void testEventDisplayedInWeekView() { openTestURL(); diff --git a/uitest/src/com/vaadin/tests/components/calendar/SetFirstVisibleHourOfDayTest.java b/uitest/src/com/vaadin/tests/components/calendar/SetFirstVisibleHourOfDayTest.java index e18163227e..a41fb8360a 100644 --- a/uitest/src/com/vaadin/tests/components/calendar/SetFirstVisibleHourOfDayTest.java +++ b/uitest/src/com/vaadin/tests/components/calendar/SetFirstVisibleHourOfDayTest.java @@ -23,6 +23,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; /** diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java index d2cb80ae67..709d3d9a60 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxIdenticalItemsTest.java @@ -15,62 +15,70 @@ */ package com.vaadin.tests.components.combobox; -import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.By; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.ComboBoxElement; /** + * Test for identical item captions in ComboBox. + * * @author Vaadin Ltd */ public class ComboBoxIdenticalItemsTest extends MultiBrowserTest { - private WebElement select; - - /* This test has been directly ported from a TB2 test */ @Test - public void identicalItemsKeyboardTest() throws Exception { + public void identicalItemsKeyboardTest() { openTestURL(); + int delay = BrowserUtil.isPhantomJS(getDesiredCapabilities()) ? 500 : 0; - // wait for the UI to be fully loaded - waitForElementVisible(By.className("v-filterselect")); - waitForElementVisible(By.id("Log")); + ComboBoxElement combobox = $(ComboBoxElement.class).first(); - select = findElement(By - .vaadin("/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]")); - select.click(); + combobox.sendKeys(delay, Keys.ARROW_DOWN, getReturn()); + waitUntilLogText("1. Item one-1 selected"); Keys[] downDownEnter = new Keys[] { Keys.ARROW_DOWN, Keys.ARROW_DOWN, - Keys.ENTER }; - sendKeys(downDownEnter); - assertLogText("1. Item one-1 selected"); + getReturn() }; - sendKeys(downDownEnter); - assertLogText("2. Item one-2 selected"); + combobox.sendKeys(delay, downDownEnter); + waitUntilLogText("2. Item one-2 selected"); - sendKeys(downDownEnter); - assertLogText("3. Item two selected"); + combobox.sendKeys(delay, downDownEnter); + waitUntilLogText("3. Item two selected"); - sendKeys(new Keys[] { Keys.ARROW_UP, Keys.ARROW_UP, Keys.ARROW_UP, - Keys.ENTER }); - assertLogText("4. Item one-1 selected"); + combobox.sendKeys(delay, new Keys[] { Keys.ARROW_UP, Keys.ARROW_UP, + Keys.ARROW_UP, getReturn() }); + waitUntilLogText("4. Item one-1 selected"); } - private void assertLogText(String expected) throws Exception { - String text = findElement(By.vaadin("PID_SLog_row_0")).getText(); - Assert.assertTrue("Expected '" + expected + "' found '" + text + "'", - text.equals(expected)); + private Keys getReturn() { + if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) { + return Keys.ENTER; + } + return Keys.RETURN; } - private void sendKeys(Keys[] keys) throws Exception { - for (Keys key : keys) { - select.sendKeys(key); - // wait a while between the key presses, at least PhantomJS fails if - // they are sent too fast - sleep(10); - } + private void waitUntilLogText(final String expected) { + waitUntil(new ExpectedCondition<Boolean>() { + private String text; + + @Override + public Boolean apply(WebDriver input) { + text = findElement(By.vaadin("PID_SLog_row_0")).getText(); + return text.equals(expected); + } + + @Override + public String toString() { + return String.format( + "log content to update. Expected: '%s' (was: '%s')", + expected, text); + } + }); } } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValue.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValue.java index b6b284c5c5..7196547861 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValue.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValue.java @@ -12,8 +12,8 @@ import com.vaadin.ui.VerticalLayout; public class ComboBoxResetValue extends AbstractTestUI { protected static final String EMPTY_VALUE = "Empty value"; - protected static final String NULL_SELECTION_ALLOWED_WITH_SET_NULL_SELECTION_ITEM_ID = "nullSelectionAllowedWithSetNullSelectionItemId"; - protected static final String NULL_SELECTION_ALLOWED_WITHOUT_NULL_SELECTION_ITEM_ID = "nullSelectionAllowedWithoutNullSelectionItemId"; + protected static final String WITH_SET_NULL_SELECTION_ITEM_ID = "nullSelectionAllowedWithSetNullSelectionItemId"; + protected static final String WITHOUT_NULL_SELECTION_ITEM_ID = "nullSelectionAllowedWithoutNullSelectionItemId"; protected static final String NULL_SELECTION_NOT_ALLOWED = "nullSelectionNotAllowed"; @Override @@ -40,7 +40,7 @@ public class ComboBoxResetValue extends AbstractTestUI { protected ComboBox getComboBoxWithNullSelectionAllowedWithSetNullSelectionItemId() { ComboBox cb = new ComboBox(); - cb.setId(NULL_SELECTION_ALLOWED_WITH_SET_NULL_SELECTION_ITEM_ID); + cb.setId(WITH_SET_NULL_SELECTION_ITEM_ID); cb.setImmediate(true); cb.setNullSelectionAllowed(true); @@ -54,7 +54,7 @@ public class ComboBoxResetValue extends AbstractTestUI { protected ComboBox getComboBoxWithNullSelectionAllowedWithoutNullSelectionItemId() { ComboBox cb = new ComboBox(); - cb.setId(NULL_SELECTION_ALLOWED_WITHOUT_NULL_SELECTION_ITEM_ID); + cb.setId(WITHOUT_NULL_SELECTION_ITEM_ID); cb.setImmediate(true); cb.setNullSelectionAllowed(true); diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValueTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValueTest.java index 3021cb6e1a..0295f4ba41 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValueTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxResetValueTest.java @@ -15,152 +15,96 @@ */ package com.vaadin.tests.components.combobox; -import static org.junit.Assert.assertEquals; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import org.junit.Test; import org.openqa.selenium.Keys; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.interactions.Actions; -import com.vaadin.testbench.By; import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.testbench.elements.ComboBoxElement; import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.ComboBoxElement; public class ComboBoxResetValueTest extends MultiBrowserTest { - static final String FILTER_STRING = "filter"; + private ComboBoxElement comboBoxWithNullSelectionItemId; + private ComboBoxElement comboBoxWithoutNullSelectionItemId; + private ComboBoxElement comboBoxWithNullNotAllowed; + + @Override + public void setup() throws Exception { + super.setup(); - @Test - public void testNullSelectionAllowedAndSetNullSelectionItemId() { openTestURL(); - ComboBoxElement comboBoxWebElement = $(ComboBoxElement.class) - .id(ComboBoxResetValue.NULL_SELECTION_ALLOWED_WITH_SET_NULL_SELECTION_ITEM_ID); + comboBoxWithNullSelectionItemId = $(ComboBoxElement.class).id( + ComboBoxResetValue.WITH_SET_NULL_SELECTION_ITEM_ID); + + comboBoxWithoutNullSelectionItemId = $(ComboBoxElement.class).id( + ComboBoxResetValue.WITHOUT_NULL_SELECTION_ITEM_ID); + + comboBoxWithNullNotAllowed = $(ComboBoxElement.class).id( + ComboBoxResetValue.NULL_SELECTION_NOT_ALLOWED); + clickResetButton(); + } - openPopup(comboBoxWebElement); + @Test + public void testNullSelectionAllowedAndSetNullSelectionItemId() { + comboBoxWithNullSelectionItemId.openPopup(); - assertEquals("There should be selected: " - + ComboBoxResetValue.EMPTY_VALUE, - ComboBoxResetValue.EMPTY_VALUE, getSelectedInPopupValue()); + assertThatNullSelectionItemSelected(comboBoxWithNullSelectionItemId); } @Test public void testFilterNullSelectionAllowedAndSetNullSelectionItemId() { - openTestURL(); + comboBoxWithNullSelectionItemId.sendKeys("foo", Keys.TAB); - ComboBoxElement comboBoxWebElement = $(ComboBoxElement.class) - .id(ComboBoxResetValue.NULL_SELECTION_ALLOWED_WITH_SET_NULL_SELECTION_ITEM_ID); - clickResetButton(); - printFilterAndRemoveIt(getComboBoxInput(comboBoxWebElement)); - - assertEquals("There should be " + ComboBoxResetValue.EMPTY_VALUE, - ComboBoxResetValue.EMPTY_VALUE, - getComboBoxValue(comboBoxWebElement)); + assertThatNullSelectionItemSelected(comboBoxWithNullSelectionItemId); } @Test public void testNullSelectionAllowedWithoutNullSelectionItemId() { - openTestURL(); + comboBoxWithoutNullSelectionItemId.openPopup(); - ComboBoxElement comboBoxWebElement = $(ComboBoxElement.class) - .id(ComboBoxResetValue.NULL_SELECTION_ALLOWED_WITHOUT_NULL_SELECTION_ITEM_ID); - clickResetButton(); - - openPopup(comboBoxWebElement); - - // not sure about expected result here.. Should be first empty string - // selected or not after reseting.. - assertEquals("There should be no selection", null, - getSelectedInPopupValue()); + assertThatSelectionIsEmpty(comboBoxWithoutNullSelectionItemId); } @Test public void testFilterNullSelectionAllowedWithoutNullSelectionItemId() { - openTestURL(); + comboBoxWithoutNullSelectionItemId.sendKeys("foo", Keys.TAB); - ComboBoxElement comboBoxWebElement = $(ComboBoxElement.class) - .id(ComboBoxResetValue.NULL_SELECTION_ALLOWED_WITHOUT_NULL_SELECTION_ITEM_ID); - clickResetButton(); - printFilterAndRemoveIt(getComboBoxInput(comboBoxWebElement)); - - assertEquals("There should be empty value", "", - getComboBoxValue(comboBoxWebElement)); + assertThatSelectionIsEmpty(comboBoxWithoutNullSelectionItemId); } @Test public void testNullSelectionNotAllowed() { - openTestURL(); + comboBoxWithNullNotAllowed.openPopup(); - ComboBoxElement comboBoxWebElement = $(ComboBoxElement.class).id( - ComboBoxResetValue.NULL_SELECTION_NOT_ALLOWED); - clickResetButton(); - - openPopup(comboBoxWebElement); - - assertEquals("There should be no selection", null, - getSelectedInPopupValue()); + assertThatSelectionIsEmpty(comboBoxWithNullNotAllowed); } @Test public void testFilterNullSelectionNotAllowed() { - openTestURL(); + comboBoxWithNullNotAllowed.sendKeys("1", Keys.TAB); + comboBoxWithNullNotAllowed.sendKeys(Keys.BACK_SPACE, Keys.TAB); - ComboBoxElement comboBoxWebElement = $(ComboBoxElement.class).id( - ComboBoxResetValue.NULL_SELECTION_NOT_ALLOWED); - clickResetButton(); - printFilterAndRemoveIt(getComboBoxInput(comboBoxWebElement)); - - assertEquals("There should be empty value", "", - getComboBoxValue(comboBoxWebElement)); + assertThat("Selection changed when it shouldn't have.", + comboBoxWithNullNotAllowed.getText(), is("1")); } - private void openPopup(ComboBoxElement comboBox) { - if (!isElementPresent(By.vaadin("#popup"))) { - comboBox.openPopup(); - } + private void assertThatNullSelectionItemSelected(ComboBoxElement comboBox) { + assertThat("Null selection item not selected.", comboBox.getText(), + is(ComboBoxResetValue.EMPTY_VALUE)); } - private String getSelectedInPopupValue() { - try { - WebElement selectedSpan = driver.findElement(By - .cssSelector(".gwt-MenuItem-selected span")); - return selectedSpan.getText(); - } catch (NoSuchElementException e) { - return null; - } catch (WebDriverException e) { - if (e.getMessage() != null - && e.getMessage().contains("Unable to find element")) { - return null; - } - throw e; - } + private void assertThatSelectionIsEmpty(ComboBoxElement comboBox) { + assertThat("Something selected when should be empty.", + comboBox.getText(), is("")); } private void clickResetButton() { ButtonElement resetButton = $(ButtonElement.class).first(); - // workaround because of IE10 that doesn't always respond to click - resetButton.focus(); - resetButton.sendKeys(Keys.ENTER); - } - - private void printFilterAndRemoveIt(WebElement target) { - Actions actions = new Actions(getDriver()); - actions.click(target).perform(); - actions.sendKeys(Keys.chord(Keys.CONTROL, "a")).perform(); // Select all - actions.sendKeys(FILTER_STRING); - actions.sendKeys(Keys.ENTER).sendKeys(Keys.ESCAPE).sendKeys(Keys.TAB); // hack - actions.perform(); - } - - private String getComboBoxValue(ComboBoxElement comboBox) { - return getComboBoxInput(comboBox).getAttribute("value"); - } - - private WebElement getComboBoxInput(ComboBoxElement comboBox) { - return comboBox.findElement(By.tagName("input")); + resetButton.click(); } } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java index bc1fe39fe5..a95301acc7 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxScrollingWithArrowsTest.java @@ -64,8 +64,7 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { public void scrollDownArrowKeyTest() throws InterruptedException { WebElement dropDownComboBox = getDropDown(); - // go to the last item and then one more - for (int i = 0; i < PAGESIZE + 1; i++) { + for (int i = 0; i < PAGESIZE; i++) { dropDownComboBox.sendKeys(Keys.DOWN); } @@ -82,8 +81,7 @@ public class ComboBoxScrollingWithArrowsTest extends MultiBrowserTest { public void scrollUpArrowKeyTest() throws InterruptedException { WebElement dropDownComboBox = getDropDown(); - // go to the last item and then one more - for (int i = 0; i < PAGESIZE + 1; i++) { + for (int i = 0; i < PAGESIZE; i++) { dropDownComboBox.sendKeys(Keys.DOWN); } diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelecting.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelecting.java new file mode 100644 index 0000000000..99f2254891 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelecting.java @@ -0,0 +1,57 @@ +package com.vaadin.tests.components.combobox; + +import com.vaadin.data.Property; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Label; +import com.vaadin.ui.TextField; + +public class ComboBoxSelecting extends AbstractTestUI { + protected ComboBox comboBox; + + @Override + protected void setup(VaadinRequest request) { + comboBox = new ComboBox(); + final Label label = new Label(); + label.setId("value"); + + comboBox.setTextInputAllowed(true); + comboBox.setNullSelectionAllowed(true); + comboBox.setNullSelectionItemId(null); + + for (char c = 'a'; c <= 'z'; c++) { + for (int i = 0; i < 100; i++) { + comboBox.addItem("" + c + i); + } + } + + comboBox.addValueChangeListener(new Property.ValueChangeListener() { + @Override + public void valueChange(Property.ValueChangeEvent event) { + Object value = event.getProperty().getValue(); + if (value != null) { + label.setValue(value.toString()); + } else { + label.setValue("null"); + } + + } + }); + + // Had to add an extra text field for our old Firefox browsers, because + // tab will otherwise send the focus to address bar and FF 24 won't fire + // a key event properly. Nice! + addComponents(comboBox, label, new TextField()); + } + + @Override + protected String getTestDescription() { + return "Clearing the filter and hitting enter should select the null item"; + } + + @Override + protected Integer getTicketNumber() { + return 15502; + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingTest.java new file mode 100644 index 0000000000..0fad2c309b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingTest.java @@ -0,0 +1,214 @@ +package com.vaadin.tests.components.combobox; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.ComboBoxElement; + +public class ComboBoxSelectingTest extends MultiBrowserTest { + + private ComboBoxElement comboBoxElement; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + waitForElementPresent(By.className("v-filterselect")); + comboBoxElement = $(ComboBoxElement.class).first(); + } + + @Test + public void firstSuggestionIsSelectedWithEnter() { + typeInputAndHitEnter("a"); + + assertThatSelectedValueIs("a0"); + } + + @Test + public void firstSuggestionIsSelectedWithTab() { + typeInputAndHitTab("a"); + + assertThatSelectedValueIs("a0"); + } + + @Test + public void nullIsSelected() { + typeInputAndHitEnter("a"); + assertThatSelectedValueIs("a0"); + + clearInputAndHitEnter(); + + assertThatSelectedValueIs("", "null"); + } + + @Test + public void itemFromSecondPageIsSelected() { + typeInputAndHitEnter("a20"); + + assertThatSelectedValueIs("a20"); + } + + @Test + public void selectingNullFromSecondPage() { + typeInputAndHitEnter("a20"); + assertThatSelectedValueIs("a20"); + + clearInputAndHitEnter(); + assertThatSelectedValueIs("", "null"); + } + + @Test + public void selectionRemainsAfterOpeningPopup() { + typeInputAndHitEnter("a20"); + assertThatSelectedValueIs("a20"); + + openPopup(); + assertThatSelectedValueIs("a20"); + } + + @Test + public void noSelectionAfterMouseOut() { + typeInputAndHitEnter("a20"); + comboBoxElement.sendKeys(Keys.ARROW_DOWN, Keys.ARROW_DOWN); + + findElement(By.className("v-app")).click(); + + assertThatSelectedValueIs("a20"); + } + + @Test + public void cancelResetsSelection() { + sendKeysToInput("a20"); + cancelSelection(); + + assertThatSelectedValueIs(""); + } + + @Test + public void inputFieldResetsToSelectedText() { + typeInputAndHitEnter("z5"); + + sendKeysToInput(Keys.BACK_SPACE, Keys.BACK_SPACE); + cancelSelection(); + + assertThatSelectedValueIs("z5"); + } + + @Test + public void emptyValueIsSelectedWithTab() { + typeInputAndHitEnter("z5"); + + assertThatSelectedValueIs("z5"); + // longer delay for this one because otherwise it keeps failing when run + // on local machine + comboBoxElement.sendKeys(200, Keys.BACK_SPACE, Keys.BACK_SPACE, + Keys.TAB); + assertThatSelectedValueIs("", "null"); + + sendKeysToInput("z5"); + cancelSelection(); + assertThatSelectedValueIs("", "null"); + } + + @Test + public void arrowNavigatedValueIsSelectedWithEnter() { + sendKeysToInput("z"); + sendKeysToInput(Keys.DOWN, Keys.DOWN, getReturn()); + + assertThatSelectedValueIs("z2"); + } + + @Test + public void arrowNavigatedValueIsSelectedWithTab() { + sendKeysToInput("z"); + sendKeysToInput(Keys.DOWN, Keys.DOWN, Keys.TAB); + + assertThatSelectedValueIs("z2"); + } + + private void clearInputAndHitEnter() { + sendKeysToInput(Keys.BACK_SPACE, Keys.BACK_SPACE, Keys.BACK_SPACE); + sendKeysToInput(getReturn()); + } + + private void typeInputAndHitEnter(String input) { + clearInputAndType(input); + sendKeysToInput(getReturn()); + } + + private void typeInputAndHitTab(String input) { + clearInputAndType(input); + sendKeysToInput(Keys.TAB); + } + + private void clearInputAndType(String input) { + comboBoxElement.clear(); + sendKeysToInput(input); + } + + private void sendKeysToInput(CharSequence... keys) { + comboBoxElement.sendKeys(keys); + } + + private Keys getReturn() { + if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) { + return Keys.ENTER; + } else { + return Keys.RETURN; + } + } + + private void openPopup() { + // Need to wait to make sure popup is closed first. + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + comboBoxElement.openPopup(); + } + + private void cancelSelection() { + if (BrowserUtil.isFirefox(getDesiredCapabilities())) { + findElement(By.className("v-app")).click(); + } else { + sendKeysToInput(Keys.ESCAPE); + } + } + + private void assertThatSelectedValueIs(final String value) { + assertThatSelectedValueIs(value, value); + } + + private void assertThatSelectedValueIs(final String value, + final String labelValue) { + assertThat(comboBoxElement.getText(), is(value)); + + waitUntil(new ExpectedCondition<Boolean>() { + private String actualValue; + + @Override + public Boolean apply(WebDriver input) { + actualValue = $(LabelElement.class).id("value").getText(); + return actualValue.equals(labelValue); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return String.format("label value to match '%s' (was: '%s')", + labelValue, actualValue); + } + }); + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowed.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowed.java new file mode 100644 index 0000000000..d941c153c3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowed.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import com.vaadin.data.Property; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Label; + +public class ComboBoxSelectingWithNewItemsAllowed extends ComboBoxSelecting { + + @Override + protected void setup(VaadinRequest request) { + super.setup(request); + comboBox.setNewItemsAllowed(true); + + final Label label = new Label(String.valueOf(comboBox.getItemIds() + .size())); + label.setCaption("Item count:"); + label.setId("count"); + comboBox.addValueChangeListener(new Property.ValueChangeListener() { + + @Override + public void valueChange(Property.ValueChangeEvent event) { + label.setValue(String.valueOf(comboBox.getItemIds().size())); + } + }); + addComponent(label); + } + + @Override + protected String getTestDescription() { + return "ComboBox should select value on TAB also when new items are allowed."; + } + + @Override + protected Integer getTicketNumber() { + return 9369; + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowedTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowedTest.java new file mode 100644 index 0000000000..c0a67514bb --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSelectingWithNewItemsAllowedTest.java @@ -0,0 +1,293 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.combobox; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.ComboBoxElement; + +public class ComboBoxSelectingWithNewItemsAllowedTest extends MultiBrowserTest { + private ComboBoxElement comboBoxElement; + private LabelElement labelElement; + + @Override + public void setup() throws Exception { + super.setup(); + + openTestURL(); + waitForElementPresent(By.className("v-filterselect")); + comboBoxElement = $(ComboBoxElement.class).first(); + labelElement = $(LabelElement.class).id("count"); + } + + @Test + public void checkDefaults() { + assertInitialItemCount(); + } + + @Test + public void itemIsAddedWithEnter() { + typeInputAndHitEnter("a"); + + assertOneMoreThanInitial(); + assertThatSelectedValueIs("a"); + } + + @Test + public void itemIsAddedWithTab() { + typeInputAndHitTab("a"); + + assertOneMoreThanInitial(); + assertThatSelectedValueIs("a"); + } + + @Test + public void matchingSuggestionIsSelectedWithEnter() { + typeInputAndHitEnter("a0"); + + assertInitialItemCount(); + assertThatSelectedValueIs("a0"); + } + + @Test + public void matchingSuggestionIsSelectedWithTab() { + typeInputAndHitTab("a0"); + + assertInitialItemCount(); + assertThatSelectedValueIs("a0"); + } + + @Test + public void nullIsSelected() { + typeInputAndHitEnter("a"); + assertOneMoreThanInitial(); + assertThatSelectedValueIs("a"); + + clearInputAndHitEnter(); + + assertOneMoreThanInitial(); + assertThatSelectedValueIs("", "null"); + } + + @Test + public void itemFromSecondPageIsSelected() { + typeInputAndHitEnter("a20"); + + assertInitialItemCount(); + assertThatSelectedValueIs("a20"); + } + + @Test + public void selectingNullFromSecondPage() { + typeInputAndHitEnter("a20"); + assertInitialItemCount(); + assertThatSelectedValueIs("a20"); + + clearInputAndHitEnter(); + assertInitialItemCount(); + assertThatSelectedValueIs("", "null"); + } + + @Test + public void selectionRemainsAfterOpeningPopup() { + typeInputAndHitEnter("a20"); + assertInitialItemCount(); + assertThatSelectedValueIs("a20"); + + openPopup(); + assertThatSelectedValueIs("a20"); + } + + @Test + public void noSelectionAfterMouseOut() { + typeInputAndHitEnter("a20"); + comboBoxElement.sendKeys(Keys.ARROW_DOWN, Keys.ARROW_DOWN); + + findElement(By.className("v-app")).click(); + + assertInitialItemCount(); + assertThatSelectedValueIs("a20"); + } + + @Test + public void cancelResetsSelection() { + sendKeysToInput("a20"); + cancelSelection(); + + assertInitialItemCount(); + assertThatSelectedValueIs(""); + } + + @Test + public void inputFieldResetsToSelectedText() { + typeInputAndHitEnter("z5"); + + sendKeysToInput(Keys.BACK_SPACE, Keys.BACK_SPACE); + cancelSelection(); + + assertInitialItemCount(); + assertThatSelectedValueIs("z5"); + } + + @Test + public void emptyValueIsSelectedWithTab() { + typeInputAndHitEnter("z5"); + + assertInitialItemCount(); + assertThatSelectedValueIs("z5"); + // longer delay for this one because otherwise it keeps failing when run + // on local machine + comboBoxElement.sendKeys(200, Keys.BACK_SPACE, Keys.BACK_SPACE, + Keys.TAB); + assertInitialItemCount(); + assertThatSelectedValueIs("", "null"); + + sendKeysToInput("z5"); + cancelSelection(); + assertInitialItemCount(); + assertThatSelectedValueIs("", "null"); + } + + @Test + public void arrowNavigatedValueIsSelectedWithEnter() { + sendKeysToInput("z"); + sendKeysToInput(Keys.DOWN, Keys.DOWN, getReturn()); + + assertInitialItemCount(); + assertThatSelectedValueIs("z1"); + } + + @Test + public void arrowNavigatedValueIsSelectedWithTab() { + sendKeysToInput("z"); + sendKeysToInput(Keys.DOWN, Keys.DOWN, Keys.TAB); + + assertInitialItemCount(); + assertThatSelectedValueIs("z1"); + } + + private void clearInputAndHitEnter() { + sendKeysToInput(Keys.BACK_SPACE, Keys.BACK_SPACE, Keys.BACK_SPACE); + sendKeysToInput(getReturn()); + } + + private void typeInputAndHitEnter(String input) { + clearInputAndType(input); + sendKeysToInput(getReturn()); + } + + private void typeInputAndHitTab(String input) { + clearInputAndType(input); + sendKeysToInput(Keys.TAB); + } + + private void clearInputAndType(String input) { + comboBoxElement.clear(); + sendKeysToInput(input); + } + + private void sendKeysToInput(CharSequence... keys) { + comboBoxElement.sendKeys(keys); + } + + private Keys getReturn() { + if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) { + return Keys.ENTER; + } else { + return Keys.RETURN; + } + } + + private void openPopup() { + // Need to wait to make sure popup is closed first. + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + comboBoxElement.openPopup(); + } + + private void cancelSelection() { + if (BrowserUtil.isFirefox(getDesiredCapabilities())) { + findElement(By.className("v-app")).click(); + } else { + sendKeysToInput(Keys.ESCAPE); + } + } + + private void assertThatSelectedValueIs(final String value) { + assertThatSelectedValueIs(value, value); + } + + private void assertThatSelectedValueIs(final String value, + final String labelValue) { + assertThat(comboBoxElement.getText(), is(value)); + + waitUntil(new ExpectedCondition<Boolean>() { + private String actualValue; + + @Override + public Boolean apply(WebDriver input) { + actualValue = $(LabelElement.class).id("value").getText(); + return actualValue.equals(labelValue); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return String.format("label value to match '%s' (was: '%s')", + labelValue, actualValue); + } + }); + } + + private void assertInitialItemCount() { + // wait for a bit in case the count is updating + try { + sleep(1000); + } catch (InterruptedException ignore) { + } + assertThat("Wrong initial item count.", labelElement.getText(), + is("2600")); + } + + private void assertOneMoreThanInitial() { + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return "2601".equals(labelElement.getText()); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return String.format("item count to become 2601 (was: %s)", + labelElement.getText()); + } + }); + } +} diff --git a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java index 7951187fa7..ce8e614e10 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboBoxSetNullWhenNewItemsAllowedTest.java @@ -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/combobox/ComboboxPageLengthZeroScrollTest.java b/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java index 948acc5fe6..e88dd2eb85 100644 --- a/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java +++ b/uitest/src/com/vaadin/tests/components/combobox/ComboboxPageLengthZeroScrollTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.components.combobox; -import java.util.Collections; import java.util.List; import org.junit.Assert; @@ -26,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; /** @@ -67,6 +67,6 @@ public class ComboboxPageLengthZeroScrollTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.singletonList(Browser.IE8.getDesiredCapabilities()); + return getBrowserCapabilities(Browser.IE8); } } diff --git a/uitest/src/com/vaadin/tests/components/customlayout/OverflowAutoFix.java b/uitest/src/com/vaadin/tests/components/customlayout/OverflowAutoFix.java new file mode 100644 index 0000000000..d6d4bdb3da --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customlayout/OverflowAutoFix.java @@ -0,0 +1,29 @@ +package com.vaadin.tests.components.customlayout; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.ui.AbstractComponent; + +@Widgetset(TestingWidgetSet.NAME) +public class OverflowAutoFix extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + addComponent(new RunOverflowFix()); + } + + public class RunOverflowFix extends AbstractComponent { + } + + @Override + public String getTestDescription() { + return "Overflow-x and overflow-y should be restored when using runWebkitOverflowAutoFix.<br>" + + "Outer size: 300x200px, inner size: 350x250px"; + } + + @Override + protected Integer getTicketNumber() { + return 16650; + } +} diff --git a/uitest/src/com/vaadin/tests/components/customlayout/OverflowAutoFixTest.java b/uitest/src/com/vaadin/tests/components/customlayout/OverflowAutoFixTest.java new file mode 100644 index 0000000000..d56e07f60b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/customlayout/OverflowAutoFixTest.java @@ -0,0 +1,43 @@ +package com.vaadin.tests.components.customlayout; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class OverflowAutoFixTest extends MultiBrowserTest { + @Test + public void testRestoreOverflowHidden() throws InterruptedException { + openTestURL(); + + click("run-button-one"); + + assertElementCssValueEquals("first-scrollbar", "overflow", "scroll"); + assertElementCssValueEquals("second-scrollbar", "overflow-x", "hidden"); + assertElementCssValueEquals("third-scrollbar", "overflow-y", "hidden"); + } + + @Test + public void testRestoreOverflowOther() throws InterruptedException { + openTestURL(); + + click("run-button-two"); + + assertElementCssValueEquals("first-scrollbar", "overflow", "visible"); + assertElementCssValueEquals("second-scrollbar", "overflow-x", "scroll"); + assertElementCssValueEquals("third-scrollbar", "overflow-y", "auto"); + } + + private void click(String className) { + findElement(By.className(className)).click(); + } + + private void assertElementCssValueEquals(String className, + String propertyName, String expected) { + Assert.assertEquals(String.format( + "Unexpected value for property '%s' on element '%s',", + propertyName, className), expected, + findElement(By.className(className)).getCssValue(propertyName)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldKeyboardInput.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldKeyboardInput.java new file mode 100644 index 0000000000..8157ce5028 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldKeyboardInput.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.datefield; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Locale; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; +import com.vaadin.ui.PopupDateField; + +public class DateFieldKeyboardInput extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Calendar c = new GregorianCalendar(Locale.ENGLISH); + c.set(2014, 0, 15); + final PopupDateField dateField = new PopupDateField("Select date", + c.getTime()); + dateField.setDateFormat("dd.MM.yyyy"); + addComponent(dateField); + dateField.addValueChangeListener(new ValueChangeListener() { + + @Override + public void valueChange(ValueChangeEvent event) { + addComponent(new Label("Date has been changed.")); + } + }); + } + + @Override + public Integer getTicketNumber() { + return 16677; + } + + @Override + public String getTestDescription() { + return "When a new date is entered in the text field using the keyboard, pressing the return key after typing the date, " + + "a label with the text 'Date has been changed' should appear."; + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/datefield/DateFieldKeyboardInputTest.java b/uitest/src/com/vaadin/tests/components/datefield/DateFieldKeyboardInputTest.java new file mode 100644 index 0000000000..15f196a26b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/datefield/DateFieldKeyboardInputTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.datefield; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DateFieldKeyboardInputTest extends MultiBrowserTest { + + @Test + public void testValueChangeEvent() { + openTestURL(); + WebElement dateFieldText = $(DateFieldElement.class).first() + .findElement(By.tagName("input")); + dateFieldText.clear(); + int numLabelsBeforeUpdate = $(LabelElement.class).all().size(); + dateFieldText.sendKeys("20.10.2013", Keys.RETURN); + int numLabelsAfterUpdate = $(LabelElement.class).all().size(); + assertTrue("Changing the date failed.", + numLabelsAfterUpdate == numLabelsBeforeUpdate + 1); + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java b/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java index a57017746a..4775441af2 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/DisabledDateFieldPopupTest.java @@ -16,7 +16,6 @@ package com.vaadin.tests.components.datefield; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import org.junit.Assert; @@ -33,13 +32,7 @@ public class DisabledDateFieldPopupTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>(); - for (DesiredCapabilities browser : super.getBrowsersToTest()) { - if (BrowserUtil.isIE(browser)) { - browsers.add(browser); - } - } - return browsers; + return getIEBrowsersOnly(); } @Test diff --git a/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java b/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java index c80a74599d..38e4b7e0b8 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/LocaleChangeTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; import org.openqa.selenium.By; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class LocaleChangeTest extends MultiBrowserTest { diff --git a/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRangeTest.java b/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRangeTest.java index 6d22048d32..a4c7248d69 100644 --- a/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRangeTest.java +++ b/uitest/src/com/vaadin/tests/components/datefield/PopupDateFieldExtendedRangeTest.java @@ -31,6 +31,7 @@ import org.openqa.selenium.interactions.Actions; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.DateFieldElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; /** @@ -405,9 +406,8 @@ public class PopupDateFieldExtendedRangeTest extends MultiBrowserTest { new Actions(driver).keyUp(Keys.SHIFT).perform(); // TODO: remove this once #14406 has been fixed - if (!getBrowsersExcludingIE().contains(getDesiredCapabilities()) - && !Browser.IE8.getDesiredCapabilities().equals( - getDesiredCapabilities())) { + if (BrowserUtil.isIE(getDesiredCapabilities()) + && !BrowserUtil.isIE8(getDesiredCapabilities())) { popup.findElement( By.className("v-datefield-calendarpanel-prevmonth")) .findElement(By.tagName("button")).click(); @@ -435,9 +435,8 @@ public class PopupDateFieldExtendedRangeTest extends MultiBrowserTest { .size()); // TODO: remove this check once #14406 has been fixed -- clicking the // button instead of navigating with arrow keys steals the focus - if (getBrowsersExcludingIE().contains(getDesiredCapabilities()) - || Browser.IE8.getDesiredCapabilities().equals( - getDesiredCapabilities())) { + if (!BrowserUtil.isIE(getDesiredCapabilities()) + || BrowserUtil.isIE8(getDesiredCapabilities())) { assertEquals( "unexpected focus", "16", diff --git a/uitest/src/com/vaadin/tests/components/embedded/EmbeddedThemeResourceTest.java b/uitest/src/com/vaadin/tests/components/embedded/EmbeddedThemeResourceTest.java index f3dca71cad..dc4dd341f4 100644 --- a/uitest/src/com/vaadin/tests/components/embedded/EmbeddedThemeResourceTest.java +++ b/uitest/src/com/vaadin/tests/components/embedded/EmbeddedThemeResourceTest.java @@ -20,7 +20,7 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import org.junit.Before; @@ -33,9 +33,10 @@ import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.EmbeddedElement; import com.vaadin.testbench.elements.ImageElement; -import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.SingleBrowserTest; import com.vaadin.ui.Embedded; +import com.vaadin.ui.Image; /** * Tests that {@link Embedded} uses correct theme when the theme is set with @@ -50,7 +51,7 @@ public class EmbeddedThemeResourceTest extends SingleBrowserTest { public List<DesiredCapabilities> getBrowsersToTest() { // Seems like stylesheet onload is not fired on PhantomJS // https://github.com/ariya/phantomjs/issues/12332 - return Arrays.asList(MultiBrowserTest.Browser.FIREFOX + return Collections.singletonList(Browser.FIREFOX .getDesiredCapabilities()); } diff --git a/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java b/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java index cc5be455cd..a9e0b03932 100644 --- a/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java @@ -24,7 +24,8 @@ import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @SuppressWarnings("boxing") diff --git a/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java b/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java index 1c00574f9c..b17416df2a 100644 --- a/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.LabelElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java index ceaceb661d..42327ebd80 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java @@ -20,7 +20,7 @@ import org.junit.Test; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.GridElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java b/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java index 46f085686d..8c601db9aa 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java @@ -20,7 +20,7 @@ import org.junit.Test; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.GridElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java b/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java index 00db02bef3..2ef1600f91 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java @@ -33,8 +33,9 @@ import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.LabelElement; import com.vaadin.testbench.elements.NativeButtonElement; import com.vaadin.testbench.elements.NativeSelectElement; -import com.vaadin.testbench.elements.ServerClass; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.elementsbase.ServerClass; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererConnector.Renderers; import com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers; @@ -57,8 +58,8 @@ public class GridClientRenderers extends MultiBrowserTest { } @Override - protected String getDeploymentPath() { - String path = super.getDeploymentPath(); + protected String getDeploymentPath(Class<?> uiClass) { + String path = super.getDeploymentPath(uiClass); if (latency > 0) { path += (path.contains("?") ? "&" : "?") + "latency=" + latency; } diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java index 6b50b64732..d99272d506 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java @@ -25,7 +25,7 @@ import org.openqa.selenium.By; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java index dcc14a967d..999f72682e 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java @@ -15,7 +15,7 @@ */ package com.vaadin.tests.components.grid; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; @TestCategory("grid") public class GridColumnAutoWidthClientTest extends diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java index 2f42b89eb1..3a4e2bfc72 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java @@ -15,7 +15,7 @@ */ package com.vaadin.tests.components.grid; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; @TestCategory("grid") public class GridColumnAutoWidthServerTest extends diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthRecalculation.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthRecalculation.java new file mode 100644 index 0000000000..43584eb5e1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthRecalculation.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import java.util.ArrayList; + +import com.vaadin.annotations.Theme; +import com.vaadin.data.Container.Indexed; +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; + +@Theme("valo") +public class GridColumnWidthRecalculation extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Grid grid = new Grid(); + + grid.addColumn("Column 1"); + grid.addColumn("Column 2"); + + grid.addRow("Narrow", + "Wiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiide"); + addComponent(grid); + + Button b = new Button("Swap content", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + swapData(grid); + } + }); + addComponent(b); + + b = new Button("Swap content and recalculate columns", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + swapData(grid); + grid.recalculateColumnWidths(); + + } + }); + addComponent(b); + } + + @SuppressWarnings("unchecked") + protected void swapData(Grid grid) { + Indexed dataSource = grid.getContainerDataSource(); + Object itemId = dataSource.getItemIds().iterator().next(); + Item item = dataSource.getItem(itemId); + ArrayList<Object> pIds = new ArrayList<Object>( + item.getItemPropertyIds()); + for (int i = 0; i < pIds.size() / 2; i++) { + int j = pIds.size() - 1 - i; + Object pid1 = pIds.get(i); + Object pid2 = pIds.get(j); + + Property<Object> property1 = item.getItemProperty(pid1); + Property<Object> property2 = item.getItemProperty(pid2); + Object tmp = property1.getValue(); + property1.setValue(property2.getValue()); + property2.setValue(tmp); + } + } + + @Override + protected String getTestDescription() { + return "There should be a way to ask Grid to recalculate column widths from server-side."; + } + + @Override + protected Integer getTicketNumber() { + return 16748; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthRecalculationTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthRecalculationTest.java new file mode 100644 index 0000000000..fab3bd8a1c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnWidthRecalculationTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.Dimension; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class GridColumnWidthRecalculationTest extends SingleBrowserTest { + + private GridElement grid; + + @Before + public void open() { + openTestURL(); + grid = $(GridElement.class).first(); + } + + @Test + public void columnWidthAfterSwap() { + int column0Width = getColumnWidth(0); + int column1Width = getColumnWidth(1); + Assert.assertTrue( + "Column 0 should be narrower than column 1 initially", + column0Width < column1Width); + + $(ButtonElement.class).caption("Swap content").first().click(); + + Assert.assertEquals( + "Column 0 width should not change when swapping contents only", + column0Width, getColumnWidth(0)); + Assert.assertEquals( + "Column 1 width should not change when swapping contents only", + column1Width, getColumnWidth(1)); + } + + @Test + public void columnWidthAfterSwapAndRecalculate() { + int column0Width = getColumnWidth(0); + int column1Width = getColumnWidth(1); + Assert.assertTrue( + "Column 0 should be narrower than column 1 initially", + column0Width < column1Width); + + $(ButtonElement.class).caption("Swap content and recalculate columns") + .first().click(); + + column0Width = getColumnWidth(0); + column1Width = getColumnWidth(1); + + Assert.assertTrue( + "Column 1 should be narrower than column 0 after resize", + column1Width < column0Width); + } + + private int getColumnWidth(int columnIndex) { + GridCellElement headerColumn = grid.getHeaderCells(0).get(columnIndex); + Dimension column1Size = headerColumn.getSize(); + int columnWidth = column1Size.getWidth(); + return columnWidth; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java index 6c386eec03..47dc90e33a 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java @@ -26,7 +26,7 @@ import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.NotificationElement; import com.vaadin.testbench.elements.PasswordFieldElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java b/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java index ffcd4c448f..d50879e65e 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java @@ -24,7 +24,7 @@ import org.junit.Test; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.NotificationElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java index 0f70d66ad4..8b3a81e660 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java @@ -23,7 +23,7 @@ import org.openqa.selenium.WebElement; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.SingleBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java b/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java index 168496e9df..f9f8d1309b 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java @@ -24,7 +24,7 @@ import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.NotificationElement; import com.vaadin.testbench.elements.TabSheetElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java index 42eb2197bf..a3fbb00cf2 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java @@ -21,7 +21,7 @@ import org.junit.Test; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.NotificationElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/GridWidthIncrease.java b/uitest/src/com/vaadin/tests/components/grid/GridWidthIncrease.java new file mode 100644 index 0000000000..6726400327 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridWidthIncrease.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; + +public class GridWidthIncrease extends AbstractTestUI { + + public static int COLUMN_COUNT = 5; + + @Override + protected void setup(VaadinRequest request) { + final Grid grid = new Grid(); + Object[] rowData = new String[COLUMN_COUNT]; + for (int i = 0; i < COLUMN_COUNT; ++i) { + grid.addColumn("Column " + i, String.class); + rowData[i] = "Foo (0, " + i + ")"; + } + grid.addRow(rowData); + grid.setWidth(400 + "px"); + addComponent(grid); + addComponent(new Button("Increase Grid Width", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + grid.setWidth((grid.getWidth() + 50) + "px"); + } + })); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java b/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java new file mode 100644 index 0000000000..96b1a56fba --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridWidthIncreaseTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridWidthIncreaseTest extends MultiBrowserTest { + + private static int INCREASE_COUNT = 3; + + @Test + public void testColumnsExpandWithGrid() throws IOException { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + + double accuracy = 1.0d; + DesiredCapabilities cap = getDesiredCapabilities(); + if (BrowserUtil.isIE(cap, 8) || BrowserUtil.isIE(cap, 9) + || BrowserUtil.isPhantomJS(cap)) { + accuracy = 2.0d; + } + + for (int i = 0; i < INCREASE_COUNT; ++i) { + $(ButtonElement.class).first().click(); + int prevWidth = 0; + for (int c = 0; c < GridWidthIncrease.COLUMN_COUNT; ++c) { + int width = grid.getCell(0, c).getSize().getWidth(); + if (c > 0) { + // check that columns are roughly the same width. + assertEquals("Difference in column widths", prevWidth, + width, accuracy); + } + prevWidth = width; + } + /* + * Column widths should be the same as table wrapper size. Since + * Selenium doesn't support subpixels correctly, we use a rough + * estimation. + */ + assertEquals(grid.getRow(0).getSize().getWidth(), grid + .getTableWrapper().getSize().getWidth(), accuracy); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java b/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java index 5d6ffbd8a7..fc93e99188 100644 --- a/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java @@ -22,7 +22,7 @@ import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.SingleBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java b/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java index 7a6d37d089..b4414a3f38 100644 --- a/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java @@ -23,7 +23,7 @@ import org.openqa.selenium.WebElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.NotificationElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java b/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java index 854d7fe3f2..063d05b735 100644 --- a/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java @@ -15,22 +15,23 @@ */ package com.vaadin.tests.components.grid; -import com.vaadin.testbench.By; -import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.testbench.elements.GridElement; -import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.testbench.elements.NotificationElement; -import com.vaadin.tests.annotations.TestCategory; -import com.vaadin.tests.tb3.MultiBrowserTest; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedCondition; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.testbench.parallel.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; /** * TB tests for the various builtin widget-based renderers. @@ -97,7 +98,8 @@ public class WidgetRenderersTest extends MultiBrowserTest { waitUntilmageSrcEndsWith(image, "window/img/maximize.png"); } - private void waitUntilmageSrcEndsWith(final WebElement image, final String expectedText) { + private void waitUntilmageSrcEndsWith(final WebElement image, + final String expectedText) { waitUntil(new ExpectedCondition<Boolean>() { @Override @@ -108,8 +110,9 @@ public class WidgetRenderersTest extends MultiBrowserTest { @Override public String toString() { // Timed out after 10 seconds waiting for ... - return String.format("image source to update. Supposed to end with '%s' (was: '%s').", - expectedText, image.getAttribute("src")); + return String + .format("image source to update. Supposed to end with '%s' (was: '%s').", + expectedText, image.getAttribute("src")); } }); } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java index 92c7f3e6a6..e03d50415c 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java @@ -26,7 +26,7 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import com.vaadin.testbench.TestBenchElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("escalator") @@ -52,6 +52,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest protected static final String GENERAL = "General"; protected static final String DETACH_ESCALATOR = "Detach Escalator"; + protected static final String ATTACH_ESCALATOR = "Attach Escalator"; protected static final String POPULATE_COLUMN_ROW = "Populate Escalator (columns, then rows)"; protected static final String POPULATE_ROW_COLUMN = "Populate Escalator (rows, then columns)"; protected static final String CLEAR_COLUMN_ROW = "Clear (columns, then rows)"; @@ -234,10 +235,10 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest } protected void scrollVerticallyTo(int px) { - executeScript("arguments[0].scrollTop = " + px, getVeticalScrollbar()); + executeScript("arguments[0].scrollTop = " + px, getVerticalScrollbar()); } - private TestBenchElement getVeticalScrollbar() { + protected TestBenchElement getVerticalScrollbar() { return (TestBenchElement) getEscalator().findElement( By.className("v-escalator-scroller-vertical")); } @@ -247,7 +248,7 @@ public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest getHorizontalScrollbar()); } - private TestBenchElement getHorizontalScrollbar() { + protected TestBenchElement getHorizontalScrollbar() { return (TestBenchElement) getEscalator().findElement( By.className("v-escalator-scroller-horizontal")); } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java index 8e07729719..8b4eb0e267 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java @@ -26,7 +26,7 @@ import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.elements.GridElement; /** - * Variant of GridBasicFeaturesTest to be used with GridBasicClientFeatures. + * GridBasicClientFeatures. * * @since * @author Vaadin Ltd diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java index 0e4f0272dd..e21f887941 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java @@ -26,24 +26,19 @@ import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; -import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") public abstract class GridBasicFeaturesTest extends MultiBrowserTest { @Override - protected DesiredCapabilities getDesiredCapabilities() { - DesiredCapabilities dCap = super.getDesiredCapabilities(); - if (BrowserUtil.isIE(dCap)) { - dCap.setCapability("requireWindowFocus", true); - } - return super.getDesiredCapabilities(); + protected boolean requireWindowFocusForIE() { + return true; } @Override diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java index 30d6541344..fb12178c9b 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java @@ -27,7 +27,7 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java index dadaff0eaa..86686225d0 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java @@ -3,7 +3,7 @@ package com.vaadin.tests.components.grid.basicfeatures; import org.junit.Test; import org.openqa.selenium.By; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @SuppressWarnings("all") diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java index d4892fb52a..685c00bbbd 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnReorderTest.java @@ -25,7 +25,7 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; /** * @@ -294,6 +294,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { public void testColumnReorder_cellsInsideSpannedHeaderAndBlockedByOtherSpannedCells_reorderingLimited() { // given toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); @@ -311,7 +312,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { scrollGridHorizontallyTo(0); assertColumnHeaderOrder(1, 2, 3, 4, 5); - dragAndDropColumnHeader(0, 3, 4, 80); + dragAndDropColumnHeader(0, 3, 4, 100); scrollGridHorizontallyTo(0); assertColumnHeaderOrder(1, 2, 3, 5, 4); @@ -319,7 +320,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { scrollGridHorizontallyTo(0); assertColumnHeaderOrder(1, 2, 3, 4, 5); - dragAndDropColumnHeader(2, 3, 4, 80); + dragAndDropColumnHeader(2, 3, 4, 100); scrollGridHorizontallyTo(0); assertColumnHeaderOrder(1, 2, 3, 5, 4); @@ -332,6 +333,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { public void testColumnReorder_cellsInsideTwoAdjacentSpannedHeaders_reorderingLimited() { // given toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); @@ -405,6 +407,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { public void testColumnReorder_cellsInsideTwoAdjacentSpannedHeaderAndFooter_reorderingLimited() { // given toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Footer", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); @@ -493,6 +496,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { public void testColumnReorder_spannedCellHasAnotherSpannedCellInside_canBeDraggedNormally() { // given toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); dragAndDropColumnHeader(1, 3, 1, 10); @@ -512,6 +516,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { public void testColumnReorder_spannedCellInsideAnotherSpanned_canBeDraggedWithBoundaries() { // given toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); dragAndDropColumnHeader(1, 3, 1, 10); @@ -539,6 +544,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { public void testColumnReorder_cellInsideAndNextToSpannedCells_canBeDraggedWithBoundaries() { // given toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); dragAndDropColumnHeader(1, 3, 1, 10); @@ -565,6 +571,7 @@ public class GridColumnReorderTest extends GridBasicClientFeaturesTest { @Test public void testColumnReorder_multipleSpannedCells_dragWorksNormally() { toggleColumnReorder(); + selectMenuPath("Component", "State", "Width", "750px"); selectMenuPath("Component", "Header", "Append row"); selectMenuPath("Component", "Header", "Row 2", "Join columns 3, 4, 5"); selectMenuPath("Component", "Header", "Append row"); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java index 79eadd03d8..ae9a8fe381 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java @@ -25,8 +25,8 @@ import org.junit.Test; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.NotificationElement; -import com.vaadin.testbench.elements.ServerClass; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.elementsbase.ServerClass; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java index 15a1cd6c85..651cd3a763 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java @@ -3,7 +3,7 @@ package com.vaadin.tests.components.grid.basicfeatures; import org.junit.Test; import com.vaadin.testbench.elements.GridElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @SuppressWarnings("all") diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java index 6a5360f152..66c937aa81 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java @@ -20,10 +20,8 @@ import java.io.IOException; import org.junit.Test; import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.tests.annotations.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; -@TestCategory("grid") public class GridSortingIndicatorsTest extends MultiBrowserTest { @Test @@ -35,5 +33,4 @@ public class GridSortingIndicatorsTest extends MultiBrowserTest { compareScreen("reversedSort"); } - } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java index 82bf349096..9e7256e0d3 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java @@ -19,9 +19,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.ArrayList; +import java.util.List; + import org.junit.Test; import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.NotificationElement; import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; import com.vaadin.tests.widgetset.client.grid.GridBasicClientFeaturesWidget; @@ -122,6 +126,35 @@ public class GridClientColumnPropertiesTest extends GridBasicClientFeaturesTest .getCell(1, 0).getText()); } + @Test + public void testColumnWidths_onColumnReorder_columnWidthsKeptTheSame() { + // given + openTestURL(); + GridElement gridElement = getGridElement(); + List<GridCellElement> headerCells = gridElement.getHeaderCells(0); + + final List<Integer> columnWidths = new ArrayList<Integer>(); + for (GridCellElement cell : headerCells) { + columnWidths.add(cell.getSize().getWidth()); + } + + // when + selectMenuPath("Component", "State", "Reverse grid columns"); + + // then + gridElement = getGridElement(); + headerCells = gridElement.getHeaderCells(0); + final int size = headerCells.size(); + for (int i = 0; i < size; i++) { + // Avoid issues with inaccuracies regarding subpixels. + assertEquals( + "Column widths don't match after reset, index after flip " + + i, columnWidths.get(i), + headerCells.get(size - 1 - i).getSize().getWidth(), 1.0d); + } + + } + private boolean cellIsFrozen(int row, int col) { return getGridElement().getCell(row, col).isFrozen(); } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java index 95ed6ab3ff..4742236ac6 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java @@ -15,11 +15,13 @@ */ package com.vaadin.tests.components.grid.basicfeatures.escalator; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import java.io.IOException; +import org.junit.Before; import org.junit.Test; import com.vaadin.testbench.elements.NotificationElement; @@ -27,20 +29,20 @@ import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeatur public class EscalatorBasicsTest extends EscalatorBasicClientFeaturesTest { - @Test - public void testDetachingAnEmptyEscalator() { + @Before + public void setUp() { setDebug(true); openTestURL(); + } + @Test + public void testDetachingAnEmptyEscalator() { selectMenuPath(GENERAL, DETACH_ESCALATOR); assertEscalatorIsRemovedCorrectly(); } @Test public void testDetachingASemiPopulatedEscalator() throws IOException { - setDebug(true); - openTestURL(); - selectMenuPath(COLUMNS_AND_ROWS, ADD_ONE_OF_EACH_ROW); selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); selectMenuPath(GENERAL, DETACH_ESCALATOR); @@ -49,14 +51,30 @@ public class EscalatorBasicsTest extends EscalatorBasicClientFeaturesTest { @Test public void testDetachingAPopulatedEscalator() { - setDebug(true); - openTestURL(); - selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); selectMenuPath(GENERAL, DETACH_ESCALATOR); assertEscalatorIsRemovedCorrectly(); } + @Test + public void testDetachingAndReattachingAnEscalator() { + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + scrollVerticallyTo(50); + scrollHorizontallyTo(50); + + selectMenuPath(GENERAL, DETACH_ESCALATOR); + selectMenuPath(GENERAL, ATTACH_ESCALATOR); + + assertEquals("Vertical scroll position", "50", getVerticalScrollbar() + .getAttribute("scrollTop")); + assertEquals("Horizontal scroll position", "50", + getHorizontalScrollbar().getAttribute("scrollLeft")); + + assertEquals("First cell of first visible row", "Row 2: 0,2", + getBodyCell(0, 0).getText()); + } + private void assertEscalatorIsRemovedCorrectly() { assertFalse($(NotificationElement.class).exists()); assertNull(getEscalator()); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRemoveAndAddRowsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRemoveAndAddRowsTest.java new file mode 100644 index 0000000000..19ba72b49d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRemoveAndAddRowsTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; + +/** + * Test class to test the escalator level issue for ticket #16832 + */ +public class EscalatorRemoveAndAddRowsTest extends + EscalatorBasicClientFeaturesTest { + + @Test + public void testRemoveAllRowsAndAddThirtyThenScroll() throws IOException { + openTestURL(); + + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + scrollVerticallyTo(99999); + assertTrue("Escalator is not scrolled to bottom.", + isElementPresent(By.xpath("//td[text() = 'Row 99: 0,99']"))); + + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_ALL_INSERT_SCROLL); + + scrollVerticallyTo(99999); + assertTrue("Escalator is not scrolled to bottom.", + isElementPresent(By.xpath("//td[text() = 'Row 29: 0,129']"))); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridClearContainer.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridClearContainer.java new file mode 100644 index 0000000000..8be2dab8fd --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridClearContainer.java @@ -0,0 +1,72 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import com.vaadin.annotations.Theme; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Grid; + +/** + * Tests that removing and adding rows doesn't cause an infinite loop in the + * browser. + * + * @author Vaadin Ltd + */ +@Theme("valo") +public class GridClearContainer extends AbstractTestUIWithLog { + + private IndexedContainer ic; + + @Override + protected void setup(VaadinRequest request) { + final Grid grid = new Grid(); + ic = new IndexedContainer(); + ic.addContainerProperty("Col 1", String.class, "default"); + ic.addItem("Row 1"); + ic.addItem("Row 2"); + grid.setContainerDataSource(ic); + + Button b = new Button("Clear and re-add", new ClickListener() { + + @SuppressWarnings("unchecked") + @Override + public void buttonClick(ClickEvent event) { + ic.removeAllItems(); + ic.addItem("Row 3").getItemProperty("Col 1") + .setValue("Updated value 1"); + ic.addItem("Row 4").getItemProperty("Col 1") + .setValue("Updated value 2"); + } + }); + addComponent(b); + addComponent(grid); + } + + @Override + protected String getTestDescription() { + return "Tests that removing and adding rows doesn't cause an infinite loop in the browser."; + } + + @Override + protected Integer getTicketNumber() { + return 16747; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridClearContainerTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridClearContainerTest.java new file mode 100644 index 0000000000..fd35dac6fc --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridClearContainerTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests that removing and adding rows doesn't cause an infinite loop in the + * browser. + * + * @author Vaadin Ltd + */ +public class GridClearContainerTest extends MultiBrowserTest { + + private final String ERRORNOTE = "Unexpected cell contents."; + + @Test + public void clearAndReadd() { + openTestURL(); + ButtonElement button = $(ButtonElement.class).caption( + "Clear and re-add").first(); + GridElement grid = $(GridElement.class).first(); + Assert.assertEquals(ERRORNOTE, "default", grid.getCell(0, 0).getText()); + Assert.assertEquals(ERRORNOTE, "default", grid.getCell(1, 0).getText()); + button.click(); + Assert.assertEquals(ERRORNOTE, "Updated value 1", grid.getCell(0, 0) + .getText()); + Assert.assertEquals(ERRORNOTE, "Updated value 2", grid.getCell(1, 0) + .getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java index c7113dbd5e..7358894e99 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridColumnReorderTest.java @@ -75,17 +75,18 @@ public class GridColumnReorderTest extends GridBasicFeaturesTest { public void testColumnReordering_reorderingTwiceBackForth_reordered() { // given openTestURL(); - assertColumnHeaderOrder(0, 1, 2); + selectMenuPath("Component", "Size", "Width", "800px"); + assertColumnHeaderOrder(0, 1, 2, 3, 4); toggleColumnReordering(); // when dragAndDropDefaultColumnHeader(2, 0, 10); // then - assertColumnHeaderOrder(2, 0, 1, 3); + assertColumnHeaderOrder(2, 0, 1, 3, 4); // when - dragAndDropDefaultColumnHeader(1, 3, 110); + dragAndDropDefaultColumnHeader(1, 3, 150); // then assertColumnHeaderOrder(2, 1, 3, 0); diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java index a61ed33029..1c0af8921b 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java @@ -32,11 +32,7 @@ public class GridMultiSortingTest extends GridBasicFeaturesTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsersToTest = super.getBrowsersToTest(); - /* FireFox and PhantomJS don't know how to press Shift key... */ - browsersToTest.remove(Browser.FIREFOX.getDesiredCapabilities()); - browsersToTest.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return browsersToTest; + return super.getBrowsersSupportingShiftClick(); } @Test diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java index 8535efb9ef..b7c33519dd 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java @@ -18,12 +18,14 @@ package com.vaadin.tests.components.grid.basicfeatures.server; import org.junit.Assert; import org.junit.Test; +import com.vaadin.testbench.elements.NotificationElement; import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; public class GridRowAddRemoveTest extends GridBasicFeaturesTest { @Test public void addRows_loadAllAtOnce() { + setDebug(true); openTestURL(); selectMenuPath("Settings", "Clear log"); @@ -54,4 +56,16 @@ public class GridRowAddRemoveTest extends GridBasicFeaturesTest { "All newly required rows should be fetched in the same round trip.", logContainsText("Requested items 37 - 55")); } + + @Test + public void testAdd18Rows() { + setDebug(true); + openTestURL(); + + selectMenuPath("Settings", "Clear log"); + selectMenuPath("Component", "Body rows", "Add 18 rows"); + + Assert.assertFalse("An error notification is present.", + isElementPresent(NotificationElement.class)); + } } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java index 7e805595c6..2d6f7acffd 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java @@ -33,11 +33,9 @@ import com.vaadin.shared.data.sort.SortDirection; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; -import com.vaadin.tests.annotations.TestCategory; import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; -@TestCategory("grid") public class GridSortingTest extends GridBasicFeaturesTest { private static class SortInfo { diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java index 08f903b3fe..e83031f227 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java @@ -233,6 +233,18 @@ public class GridStructureTest extends GridBasicFeaturesTest { } @Test + public void testRemoveFirstRowTwice() { + openTestURL(); + + selectMenuPath("Component", "Body rows", "Remove first row"); + selectMenuPath("Component", "Body rows", "Remove first row"); + + getGridElement().scrollToRow(50); + assertFalse("Listener setup problem occurred.", + logContainsText("AssertionError: Value change listeners")); + } + + @Test public void testVerticalScrollBarVisibilityWhenEnoughRows() throws Exception { openTestURL(); diff --git a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java index 64b9997dcc..22c9c0d4e3 100644 --- a/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java +++ b/uitest/src/com/vaadin/tests/components/gridlayout/GridLayoutExtraSpacingTest.java @@ -25,6 +25,7 @@ import org.openqa.selenium.WebElement; import com.vaadin.testbench.elements.CheckBoxElement; import com.vaadin.testbench.elements.CssLayoutElement; import com.vaadin.testbench.elements.GridLayoutElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class GridLayoutExtraSpacingTest 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..4009365814 100644 --- a/uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java +++ b/uitest/src/com/vaadin/tests/components/javascriptcomponent/JavaScriptPreloadingTest.java @@ -29,23 +29,11 @@ import org.openqa.selenium.support.ui.WebDriverWait; import com.vaadin.tests.tb3.MultiBrowserTest; -/** - * - * @since - * @author Vaadin Ltd - */ public class JavaScriptPreloadingTest extends MultiBrowserTest { - /* - * (non-Javadoc) - * - * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() - */ @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return browsers; + return getBrowsersExcludingPhantomJS(); } @Test diff --git a/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java b/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java index 3cfe30a991..a460290ee0 100644 --- a/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java +++ b/uitest/src/com/vaadin/tests/components/menubar/MenuBarTooltipsNearEdgeTest.java @@ -41,11 +41,8 @@ public class MenuBarTooltipsNearEdgeTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - // Tooltip tests work unreliably on IE due to an issue with the - // WebDriver (see #13854) - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - return browsers; + // Tooltip test is unreliable on IE8 + return getBrowsersExcludingIE8(); }; @Test @@ -59,6 +56,5 @@ public class MenuBarTooltipsNearEdgeTest extends MultiBrowserTest { WebElement tooltip = getTooltipElement(); assertThat(tooltip.getLocation().x, is(lessThan(menuLocation.onPage().x - tooltip.getSize().getWidth()))); - } } diff --git a/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java b/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java index eb838c135e..4e23db8eb7 100644 --- a/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java +++ b/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsAndChromeKeyboardNavigationTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.components.nativeselect; -import java.util.Collections; import java.util.List; import org.junit.Assert; @@ -26,25 +25,15 @@ 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 - */ public class NativeSelectsAndChromeKeyboardNavigationTest extends MultiBrowserTest { - /* - * (non-Javadoc) - * - * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() - */ @Override public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.singletonList(Browser.CHROME - .getDesiredCapabilities()); + return getBrowserCapabilities(Browser.CHROME); } @Test @@ -72,30 +61,17 @@ public class NativeSelectsAndChromeKeyboardNavigationTest extends } - /* - * (non-Javadoc) - * - * @see com.vaadin.tests.tb3.AbstractTB3Test#getUIClass() - */ @Override protected Class<?> getUIClass() { return NativeSelects.class; } - /** - * @since - * @param string - */ private void menuSub(String string) { getDriver().findElement(By.xpath("//span[text() = '" + string + "']")) .click(); new Actions(getDriver()).moveByOffset(100, 0).build().perform(); } - /** - * @since - * @param string - */ private void menu(String string) { getDriver().findElement(By.xpath("//span[text() = '" + string + "']")) .click(); diff --git a/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsFocusAndBlurListenerTests.java b/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsFocusAndBlurListenerTests.java index bf81ca4390..194b1bb64b 100644 --- a/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsFocusAndBlurListenerTests.java +++ b/uitest/src/com/vaadin/tests/components/nativeselect/NativeSelectsFocusAndBlurListenerTests.java @@ -21,6 +21,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.interactions.Actions; import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class NativeSelectsFocusAndBlurListenerTests extends MultiBrowserTest { diff --git a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java index 252efe2824..33ba8d1df0 100644 --- a/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java +++ b/uitest/src/com/vaadin/tests/components/notification/NotificationsWaiAriaTest.java @@ -31,7 +31,7 @@ import com.vaadin.tests.tb3.MultiBrowserTest; /** * Unit test class for Notification ARIA (Accessible Rich Internet Applications) * roles. - * + * * @since 7.2 * @author Vaadin Ltd */ @@ -39,7 +39,7 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest { /** * Checks if the ARIA roles are correctly applied to Notification. - * + * * @since 7.2 * @throws Exception */ @@ -80,10 +80,7 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest { Assert.assertTrue("Expected '- press ESC to close', found " + text, text.equals("- press ESC to close")); - try { - notification.closeNotification(); - } catch (Exception e) { - } + notification.close(); type.selectByText(StringToEnumConverter.enumToString( NotificationRole.STATUS, null)); @@ -97,10 +94,7 @@ public class NotificationsWaiAriaTest extends MultiBrowserTest { Assert.assertTrue("Expected attribute 'role' to equal 'status', found " + text, text.equals("status")); - try { - notification.closeNotification(); - } catch (Exception e) { - } + notification.close(); prefix.clear(); postfix.clear(); diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java index a95ceca22b..9bb53d8742 100644 --- a/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/CaptionLeakTest.java @@ -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..0890414fea 100644 --- a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java @@ -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 (BrowserUtil.isIE8(capabilities) + || BrowserUtil.isIE(capabilities, 9)) { // 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 (BrowserUtil.isIE8(capabilities) + || BrowserUtil.isIE(capabilities, 9)) { // IE8 and IE9 insert cursor in the start of input instead of end. Assert.assertEquals(secondText + firstText, tf2.getAttribute("value")); @@ -96,5 +97,4 @@ public class VerticalLayoutFocusWithDOMChangesTest extends MultiBrowserTest { tf2.getAttribute("value")); } } - } diff --git a/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java b/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java index ce528df373..aafd310b70 100644 --- a/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java +++ b/uitest/src/com/vaadin/tests/components/popupview/PopupViewResizeWhileOpenTest.java @@ -20,7 +20,6 @@ import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; -import java.util.Collections; import java.util.List; import org.junit.Test; @@ -32,6 +31,7 @@ import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.PopupViewElement; import com.vaadin.testbench.elements.VerticalLayoutElement; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; /** @@ -75,6 +75,6 @@ public class PopupViewResizeWhileOpenTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.singletonList(Browser.IE8.getDesiredCapabilities()); + return getBrowserCapabilities(Browser.IE8); } } diff --git a/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java index 897511e41a..68b3748472 100644 --- a/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java +++ b/uitest/src/com/vaadin/tests/components/table/AddSelectionToRemovedRangeTest.java @@ -16,8 +16,6 @@ package com.vaadin.tests.components.table; import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import org.junit.Assert; @@ -29,22 +27,19 @@ 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 { @Override - public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.unmodifiableList(Arrays.asList(Browser.CHROME - .getDesiredCapabilities())); + protected boolean requireWindowFocusForIE() { + return true; } @Override - protected DesiredCapabilities getDesiredCapabilities() { - DesiredCapabilities cap = new DesiredCapabilities( - super.getDesiredCapabilities()); - cap.setCapability("requireWindowFocus", true); - return cap; + public List<DesiredCapabilities> getBrowsersToTest() { + return getBrowserCapabilities(Browser.CHROME); } @Test diff --git a/uitest/src/com/vaadin/tests/components/table/ContextMenuSizeTest.java b/uitest/src/com/vaadin/tests/components/table/ContextMenuSizeTest.java index 6583406fd2..e6b3ca2af4 100644 --- a/uitest/src/com/vaadin/tests/components/table/ContextMenuSizeTest.java +++ b/uitest/src/com/vaadin/tests/components/table/ContextMenuSizeTest.java @@ -15,17 +15,19 @@ */ package com.vaadin.tests.components.table; -import java.util.ArrayList; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.lessThan; + import java.util.List; -import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.By; -import org.openqa.selenium.Dimension; 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; /** @@ -35,85 +37,40 @@ import com.vaadin.tests.tb3.MultiBrowserTest; */ public class ContextMenuSizeTest extends MultiBrowserTest { - @Test - public void testContextMenuBottom() { - openTestURL(); - - WebElement menu = openContextMenu(); - int initialHeight = menu.getSize().getHeight(); - int y = menu.getLocation().getY(); - - closeContextMenu(); - - Dimension size = getDriver().manage().window().getSize(); - - int windowHeight = y + initialHeight - 10; - if (isElementPresent(By.className("v-ff"))) { - // FF does something wrong with window height - windowHeight = y + initialHeight + 90; - } else if (isElementPresent(By.className("v-ch"))) { - // Chrome does something wrong with window height - windowHeight = y + initialHeight + 50; - } - getDriver().manage().window() - .setSize(new Dimension(size.getWidth(), windowHeight)); - - menu = openContextMenu(); - int height = menu.getSize().getHeight(); + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // context menu doesn't work in phantom JS and works weirdly with IE8 + // and selenium. + return getBrowserCapabilities(Browser.IE9, Browser.IE10, Browser.IE11, + Browser.FIREFOX, Browser.CHROME); + } - Assert.assertEquals("Context menu height has been changed after " - + "window height update which allows to show context as is", - initialHeight, height); + @Override + public void setup() throws Exception { + super.setup(); + openTestURL(); } - @Test - public void testContextMenuSize() { - openTestURL(); + private void resizeViewPortHeightTo(int windowHeight) { + // viewport width doesn't matter, let's use a magic number of 500. + testBench().resizeViewPortTo(500, windowHeight); + } - WebElement menu = openContextMenu(); - int initialHeight = menu.getSize().getHeight(); - int y = menu.getLocation().getY(); + private int getContextMenuY() { + int y = openContextMenu().getLocation().getY(); closeContextMenu(); - Dimension size = getDriver().manage().window().getSize(); - - int windowHeight = initialHeight - 10; - if (isElementPresent(By.className("v-ch"))) { - // Chrome does something wrong with window height - windowHeight = y + initialHeight; - } - getDriver().manage().window() - .setSize(new Dimension(size.getWidth(), windowHeight)); + return y; + } - menu = openContextMenu(); - int height = menu.getSize().getHeight(); + private int getContextMenuHeight() { + int height = openContextMenu().getSize().getHeight(); - Assert.assertTrue( - "Context menu height has not been descreased after " - + "window height update to value lower than context menu initial height", - initialHeight > height); closeContextMenu(); - getDriver().manage().window() - .setSize(new Dimension(size.getWidth(), size.getHeight())); - menu = openContextMenu(); - height = menu.getSize().getHeight(); - Assert.assertEquals("Context menu height has not been reset after " - + "window height reset", initialHeight, height); - } - - @Override - public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - getAllBrowsers()); - - // context menu doesn't work in phantom JS and works wired with IE8 and - // selenium. - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - return browsers; + return height; } private WebElement openContextMenu() { @@ -124,8 +81,29 @@ public class ContextMenuSizeTest extends MultiBrowserTest { } private void closeContextMenu() { - Actions actions = new Actions(getDriver()); - actions.click().build().perform(); + findElement(By.className("v-app")).click(); + } + + @Test + public void contextMenuIsResizedToFitWindow() { + int initialHeight = getContextMenuHeight(); + + resizeViewPortHeightTo(initialHeight - 10); + assertThat(getContextMenuHeight(), lessThan(initialHeight)); + + resizeViewPortHeightTo(initialHeight + 100); + assertThat(getContextMenuHeight(), is(initialHeight)); + } + + @Test + public void contextMenuPositionIsChangedAfterResize() { + int height = getContextMenuHeight(); + int y = getContextMenuY(); + + resizeViewPortHeightTo(y + height - 10); + + assertThat(getContextMenuY(), lessThan(y)); + assertThat(getContextMenuHeight(), is(height)); } } diff --git a/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java b/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java index 026d672044..add7db93f2 100644 --- a/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java +++ b/uitest/src/com/vaadin/tests/components/table/CtrlShiftMultiselectTest.java @@ -31,12 +31,7 @@ public class CtrlShiftMultiselectTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - // Shift + click doesn't select all rows correctly on these browsers - browsers.remove(Browser.FIREFOX.getDesiredCapabilities()); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - - return browsers; + return getBrowsersSupportingShiftClick(); } @Override diff --git a/uitest/src/com/vaadin/tests/components/table/DisabledSortingTable.java b/uitest/src/com/vaadin/tests/components/table/DisabledSortingTable.java new file mode 100644 index 0000000000..6dc68de509 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/DisabledSortingTable.java @@ -0,0 +1,60 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Table; + +public class DisabledSortingTable extends AbstractTestUI { + + @SuppressWarnings("unchecked") + @Override + protected void setup(VaadinRequest request) { + final Table table = new Table(); + + table.addContainerProperty("header1", String.class, "column1"); + table.addContainerProperty("header2", String.class, "column2"); + table.addContainerProperty("header3", String.class, "column3"); + + for (int row = 0; row < 5; row++) { + Object key = table.addItem(); + table.getItem(key).getItemProperty("header1") + .setValue(String.valueOf(row)); + table.getItem(key).getItemProperty("header2") + .setValue(String.valueOf(5 - row)); + } + + addComponent(table); + + addButton("Enable sorting", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + table.setSortEnabled(true); + } + }); + + addButton("Disable sorting", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + table.setSortEnabled(false); + } + }); + + addButton("Sort by empty array", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + table.sort(new Object[] {}, new boolean[] {}); + } + }); + } + + @Override + public String getTestDescription() { + return "Sorting with empty arrays should hide sorting indicator but not reset sorting in Table with default container."; + } + + @Override + protected Integer getTicketNumber() { + return 16563; + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/DisabledSortingTableSqlContainer.java b/uitest/src/com/vaadin/tests/components/table/DisabledSortingTableSqlContainer.java new file mode 100644 index 0000000000..bc4cd717bf --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/DisabledSortingTableSqlContainer.java @@ -0,0 +1,44 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.Button; + +public class DisabledSortingTableSqlContainer extends TableSqlContainer { + + @Override + protected void setup(VaadinRequest request) { + super.setup(request); + + addButton("Enable sorting", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + table.setSortEnabled(true); + } + }); + + addButton("Disable sorting", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + table.setSortEnabled(false); + } + }); + + addButton("Sort by empty array", new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + table.sort(new Object[] {}, new boolean[] {}); + } + }); + } + + @Override + protected String getTestDescription() { + return "Sorting with empty arrays should reset sorting and hide sorting indicator in Table connected to a SQLContainer"; + } + + @Override + protected Integer getTicketNumber() { + return 16563; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/DisabledSortingTableTest.java b/uitest/src/com/vaadin/tests/components/table/DisabledSortingTableTest.java new file mode 100644 index 0000000000..bb15301eee --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/DisabledSortingTableTest.java @@ -0,0 +1,99 @@ +package com.vaadin.tests.components.table; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class DisabledSortingTableTest extends MultiBrowserTest { + + Class<?> uiClass; + + @Override + protected java.lang.Class<?> getUIClass() { + return uiClass; + }; + + @Test + public void sortingByEmptyArrayShouldClearSortingIndicator() { + uiClass = DisabledSortingTable.class; + openTestURL(); + + assertThatFirstCellHasText("0"); + + sortFirstColumnAscending(); + assertThatFirstCellHasText("4"); + + disableSorting(); + + sortByEmptyArray(); + assertThatFirstCellHasText("4"); + } + + @Test + public void emptySortingClearsIndicatorAndResetsSortingWithSQLContainer() { + uiClass = DisabledSortingTableSqlContainer.class; + openTestURL(); + + assertThatFirstCellHasText("1"); + + sortFirstColumnAscending(); + assertThatFirstCellHasText("2"); + + disableSorting(); + sortByEmptyArray(); + + assertThatFirstCellHasText("1"); + } + + private void sortFirstColumnAscending() { + getFirstColumnHeader().click(); + waitUntilHeaderHasExpectedClass("v-table-header-cell-asc"); + } + + private TestBenchElement getFirstColumnHeader() { + return getTable().getHeaderCell(1); + } + + private TableElement getTable() { + return $(TableElement.class).first(); + } + + private void assertThatFirstCellHasText(String text) { + assertThat(getTable().getCell(0, 0).getText(), is(text)); + } + + private void sortByEmptyArray() { + $(ButtonElement.class).caption("Sort by empty array").first().click(); + + waitUntilHeaderHasExpectedClass("v-table-header-cell"); + } + + private void disableSorting() { + $(ButtonElement.class).caption("Disable sorting").first().click(); + } + + protected void waitUntilHeaderHasExpectedClass(final String className) { + final TestBenchElement header = getFirstColumnHeader(); + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + return className.equals(header.getAttribute("class")); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return String + .format("header to get class name '%s'", className); + } + }); + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java index b4b8d93fbe..b254d27b58 100644 --- a/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java +++ b/uitest/src/com/vaadin/tests/components/table/MemoryLeakTableTest.java @@ -26,21 +26,18 @@ import org.openqa.selenium.WebElement; import com.vaadin.testbench.elements.ButtonElement; import com.vaadin.testbench.elements.TableElement; -import com.vaadin.tests.tb3.AbstractTB3Test.RunLocally; 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 * lead in Table component. This test should not be used in auto testing. - * + * * To test memory consuption. Run test in debug mode. Take memory snapshot in * Profiler in browser before and after the loop. Compare memory consuption. - * + * * @since * @author Vaadin Ltd */ -@RunLocally(Browser.CHROME) public class MemoryLeakTableTest extends MultiBrowserTest { /** diff --git a/uitest/src/com/vaadin/tests/components/table/ReloadWidgets.java b/uitest/src/com/vaadin/tests/components/table/ReloadWidgets.java new file mode 100644 index 0000000000..ef72f92a4e --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/ReloadWidgets.java @@ -0,0 +1,118 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.data.util.BeanItemContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Table; + +@SuppressWarnings("serial") +public class ReloadWidgets extends AbstractTestUI { + + int pressed = 0; + + @Override + protected void setup(VaadinRequest request) { + + final Table table = new Table(null, new BeanItemContainer<Bean>( + Bean.class)); + table.setId("table"); + table.setSizeFull(); + + table.setColumnHeader("col1", "Text"); + table.setColumnHeader("col2", "Button"); + + fillTable(table); + + Button button = new Button("Refresh"); + button.setId("refresh"); + button.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + table.removeAllItems(); + fillTable(table); + } + }); + getLayout().addComponent(button); + getLayout().addComponent(table); + getLayout().setExpandRatio(table, 1f); + } + + @Override + protected String getTestDescription() { + return "Table should always populate button widgets to column 2"; + } + + @Override + protected Integer getTicketNumber() { + return 16611; + } + + private void fillTable(Table table) { + int i = 0; + int size = pressed % 2 == 0 ? 500 : 499; + pressed++; + for (int step = 0; step < i + size; step++) { + String caption = Integer.toString(step); + Button button = new Button(caption); + button.setId(caption); + Bean itemId = new Bean(caption, button); + table.addItem(itemId); + } + } + + public class Bean { + private String col1; + private Button col2; + + public Bean(String col1, Button col2) { + this.col1 = col1; + this.col2 = col2; + } + + public String getCol1() { + return col1; + } + + public void setCol1(String col1) { + this.col1 = col1; + } + + public Button getCol2() { + return col2; + } + + public void setCol2(Button col2) { + this.col2 = col2; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Bean bean = (Bean) o; + + if (!col1.equals(bean.col1)) { + return false; + } + if (!col2.equals(bean.col2)) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = col1.hashCode(); + result = 31 * result + col2.hashCode(); + return result; + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/table/ReloadWidgetsTest.java b/uitest/src/com/vaadin/tests/components/table/ReloadWidgetsTest.java new file mode 100644 index 0000000000..c92e00ab29 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/table/ReloadWidgetsTest.java @@ -0,0 +1,80 @@ +package com.vaadin.tests.components.table; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ReloadWidgetsTest extends MultiBrowserTest { + + private int rowHeight = -1; + + private WebElement wrapper; + + @Override + public void setup() throws Exception { + super.setup(); + openTestURL(); + + TableElement table = $(TableElement.class).id("table"); + rowHeight = table.getCell(1, 0).getLocation().getY() + - table.getCell(0, 0).getLocation().getY(); + + wrapper = findElement(By.className("v-table-body-wrapper")); + } + + @Test + public void testScrollingThenUpdatingContents() throws Exception { + // Scroll down to row 44 so that we get the cut-off point where the + // problem becomes apparent + testBenchElement(wrapper).scroll(44 * rowHeight); + waitForScrollToFinish(); + + // Assert that we have the button widget. + Assert.assertTrue( + "Button widget was not found after scrolling for the first time", + !findElements(By.id("46")).isEmpty()); + + // Now refresh the container contents + WebElement refreshButton = findElement(By.id("refresh")); + refreshButton.click(); + + // Again scroll down to row 44 so we get the cut-off point visible + testBenchElement(wrapper).scroll(44 * rowHeight); + waitForScrollToFinish(); + + // Assert that we still get the button + Assert.assertTrue( + "Button widget was not found after refreshing container items.", + !findElements(By.id("46")).isEmpty()); + } + + /** + * Waits until the scroll position indicator goes away, signifying that all + * the required rows have been fetched. + */ + private void waitForScrollToFinish() { + waitUntil(new ExpectedCondition<Boolean>() { + @Override + public Boolean apply(WebDriver input) { + List<WebElement> elements = findElements(By + .className("v-table-scrollposition")); + return elements.isEmpty() || !elements.get(0).isDisplayed(); + } + + @Override + public String toString() { + // Timed out after 10 seconds waiting for ... + return "scroll position indicator to vanish"; + } + }); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java index f6c6ca3ddc..175cbac9d5 100644 --- a/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java +++ b/uitest/src/com/vaadin/tests/components/table/SelectAllRowsTest.java @@ -18,7 +18,6 @@ package com.vaadin.tests.components.table; import static com.vaadin.tests.components.table.SelectAllRows.TOTAL_NUMBER_OF_ROWS; import static org.junit.Assert.assertEquals; -import java.util.ArrayList; import java.util.List; import org.junit.Test; @@ -51,12 +50,7 @@ public class SelectAllRowsTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - // Pressing Shift modifier key does not work with Firefox and PhantomJS - ArrayList<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - super.getBrowsersToTest()); - browsers.remove(Browser.FIREFOX.getDesiredCapabilities()); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return browsers; + return getBrowsersSupportingShiftClick(); } @Test diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthIE8Test.java b/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthIE8Test.java index 8bace7e23a..3de2ceb200 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthIE8Test.java +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthIE8Test.java @@ -1,26 +1,23 @@ package com.vaadin.tests.components.table; -import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.testbench.elements.TableElement; -import com.vaadin.tests.tb3.MultiBrowserTest; +import static org.junit.Assert.assertEquals; + +import java.util.List; + import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; -import java.util.ArrayList; -import java.util.List; - -import static org.junit.Assert.assertEquals; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.testbench.parallel.Browser; +import com.vaadin.tests.tb3.MultiBrowserTest; public class TableColumnResizeContentsWidthIE8Test extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsersToTest = new ArrayList<DesiredCapabilities>(); - - browsersToTest.add(Browser.IE8.getDesiredCapabilities()); - - return browsersToTest; + return getBrowserCapabilities(Browser.IE8); } @Override diff --git a/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthTest.java b/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthTest.java index 5faee3cc59..9072d13263 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthTest.java +++ b/uitest/src/com/vaadin/tests/components/table/TableColumnResizeContentsWidthTest.java @@ -15,9 +15,10 @@ */ package com.vaadin.tests.components.table; -import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.testbench.elements.TableElement; -import com.vaadin.tests.tb3.MultiBrowserTest; +import static org.junit.Assert.assertEquals; + +import java.util.List; + import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -26,9 +27,9 @@ import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; -import java.util.List; - -import static org.junit.Assert.assertEquals; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.TableElement; +import com.vaadin.tests.tb3.MultiBrowserTest; /** * Tests that components within table cells get resized when their column gets @@ -40,13 +41,7 @@ public class TableColumnResizeContentsWidthTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsersToTest = super.getBrowsersToTest(); - - // Can't get IE8 to hit the resizer, extracted IE8 to it's own test - // class. - browsersToTest.remove(Browser.IE8.getDesiredCapabilities()); - - return browsersToTest; + return getBrowsersExcludingIE8(); } @Test diff --git a/uitest/src/com/vaadin/tests/components/table/TableNavigationPageDownTest.java b/uitest/src/com/vaadin/tests/components/table/TableNavigationPageDownTest.java index fc3fd2610c..4ab42a5f94 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableNavigationPageDownTest.java +++ b/uitest/src/com/vaadin/tests/components/table/TableNavigationPageDownTest.java @@ -18,7 +18,6 @@ package com.vaadin.tests.components.table; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import java.util.ArrayList; import java.util.List; import org.junit.Test; @@ -31,6 +30,7 @@ import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.elements.TableElement; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; /** @@ -47,15 +47,11 @@ public class TableNavigationPageDownTest extends MultiBrowserTest { private WebElement wrapper; - @Override public List<DesiredCapabilities> getBrowsersToTest() { // Sending PageDown has no effect on PhantomJS. On IE focus // in Table is often lost, so default scrolling happens on PageDown. - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - getBrowsersExcludingIE()); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return browsers; + return getBrowserCapabilities(Browser.FIREFOX, Browser.CHROME); } @Override @@ -73,7 +69,7 @@ public class TableNavigationPageDownTest extends MultiBrowserTest { } private void sendKeyUntilEndIsReached(Keys key) { - while(true) { + while (true) { int lastVisibleRowNumber = getLastVisibleRowNumber(); sendKey(key); @@ -116,7 +112,8 @@ public class TableNavigationPageDownTest extends MultiBrowserTest { @Test public void navigatePageDown() { - // Scroll to a point where you can reach the bottom with a couple of page downs. + // Scroll to a point where you can reach the bottom with a couple of + // page downs. // Can't use v-table-body height because lower rows haven't been // fetched yet. testBenchElement(wrapper).scroll( @@ -132,7 +129,8 @@ public class TableNavigationPageDownTest extends MultiBrowserTest { @Test public void navigatePageUp() { - // Scroll to a point where you can reach the top with a couple of page ups. + // Scroll to a point where you can reach the top with a couple of page + // ups. testBenchElement(wrapper).scroll((int) (2.8 * pageHeight)); waitForScrollToFinish(); diff --git a/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java index 9242bae3d8..d390b57823 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java +++ b/uitest/src/com/vaadin/tests/components/table/TableScrollAfterAddRowTest.java @@ -31,10 +31,6 @@ import com.vaadin.testbench.screenshot.ImageComparison; import com.vaadin.testbench.screenshot.ReferenceNameGenerator; import com.vaadin.tests.tb3.MultiBrowserTest; -/** - * - * @author Vaadin Ltd - */ public class TableScrollAfterAddRowTest extends MultiBrowserTest { @Before @@ -45,6 +41,7 @@ public class TableScrollAfterAddRowTest extends MultiBrowserTest { @Test public void testJumpToFirstRow() throws InterruptedException { jumpToFifteenthRow(); + sleep(300); jumpToFirstRow(); assertEquals("0", getCurrentPageFirstItemIndex()); } diff --git a/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java index 0b40af94a2..3b5949dd40 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java +++ b/uitest/src/com/vaadin/tests/components/table/TableSqlContainer.java @@ -21,13 +21,15 @@ import com.vaadin.ui.VerticalLayout; public class TableSqlContainer extends AbstractTestUI { + protected Table table; + @Override protected void setup(VaadinRequest request) { setLocale(Locale.ENGLISH); VerticalLayout layout = new VerticalLayout(); addComponent(layout); - final Table table = new Table("Table with SQLContainer"); + table = new Table("Table with SQLContainer"); layout.addComponent(table); final Label selectedLabel = new Label("Selected: null"); diff --git a/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java b/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java index 3e12333a6d..14994f8b02 100644 --- a/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java +++ b/uitest/src/com/vaadin/tests/components/table/TableWithPollingTest.java @@ -88,8 +88,6 @@ public class TableWithPollingTest extends MultiBrowserTest { // Selenium has issues with drag-and-drop on IE8 making it impossible to // drag a target as small as the table resizer. So we'll just have to // ignore IE8 completely. - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - return browsers; + return getBrowsersExcludingIE8(); } } diff --git a/uitest/src/com/vaadin/tests/components/table/UnnecessaryScrollbarWhenZoomingTest.java b/uitest/src/com/vaadin/tests/components/table/UnnecessaryScrollbarWhenZoomingTest.java index df01800180..f0325ed77b 100644 --- a/uitest/src/com/vaadin/tests/components/table/UnnecessaryScrollbarWhenZoomingTest.java +++ b/uitest/src/com/vaadin/tests/components/table/UnnecessaryScrollbarWhenZoomingTest.java @@ -34,6 +34,7 @@ import org.openqa.selenium.support.ui.WebDriverWait; import com.vaadin.testbench.By; import com.vaadin.testbench.commands.TestBenchCommandExecutor; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class UnnecessaryScrollbarWhenZoomingTest 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..52003bbac9 100644 --- a/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java +++ b/uitest/src/com/vaadin/tests/components/tabsheet/TabSheetFocusedTabTest.java @@ -33,11 +33,9 @@ public class TabSheetFocusedTabTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); // PhantomJS doesn't send Focus / Blur events when clicking or // navigating with keyboard - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return browsers; + return getBrowsersExcludingPhantomJS(); } @Override diff --git a/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java index ab398035ac..760d2f39ea 100644 --- a/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java +++ b/uitest/src/com/vaadin/tests/components/ui/ComboboxSelectedItemTextTest.java @@ -16,13 +16,16 @@ package com.vaadin.tests.components.ui; import java.io.IOException; +import java.util.List; import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.By; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; /** @@ -40,6 +43,13 @@ public class ComboboxSelectedItemTextTest extends MultiBrowserTest { public final int INDEX_EDITABLE_COMBOBOX = 1; public final int INDEX_NON_EDITABLE_COMBOBOX = 2; + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // Ignoring Chrome 40 because of a regression. See #16636. + return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10, + Browser.IE11, Browser.FIREFOX, Browser.PHANTOMJS); + } + @Test public void testCombobox() throws IOException { testCombobox(INDEX_EDITABLE_COMBOBOX, INDEX_NON_EDITABLE_COMBOBOX, diff --git a/uitest/src/com/vaadin/tests/components/ui/DynamicViewportEmptyTest.java b/uitest/src/com/vaadin/tests/components/ui/DynamicViewportEmptyTest.java index 40ec937c1c..55466130ad 100644 --- a/uitest/src/com/vaadin/tests/components/ui/DynamicViewportEmptyTest.java +++ b/uitest/src/com/vaadin/tests/components/ui/DynamicViewportEmptyTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.components.ui; -import java.util.Arrays; import java.util.List; import org.junit.Assert; @@ -24,6 +23,7 @@ import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.MultiBrowserTest; public class DynamicViewportEmptyTest extends MultiBrowserTest { @@ -35,7 +35,7 @@ public class DynamicViewportEmptyTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - return Arrays.asList(Browser.CHROME.getDesiredCapabilities()); + return getBrowserCapabilities(Browser.CHROME); } @Test diff --git a/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java index fca312ba7e..43422feb58 100644 --- a/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java +++ b/uitest/src/com/vaadin/tests/components/ui/TextAreaEventPropagationModifierKeysTest.java @@ -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 { @@ -67,17 +68,9 @@ public class TextAreaEventPropagationModifierKeysTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - // Can't handle ctrl - browsers.remove(Browser.IE8.getDesiredCapabilities()); - browsers.remove(Browser.FIREFOX.getDesiredCapabilities()); - - // Can't handle shift or ctrl - browsers.remove(Browser.IE9.getDesiredCapabilities()); - browsers.remove(Browser.IE10.getDesiredCapabilities()); - browsers.remove(Browser.IE11.getDesiredCapabilities()); - return browsers; - + // IE8 and Firefox can't handle ctrl. + // IE9-11 has issues with shift and ctrl + return getBrowserCapabilities(Browser.CHROME, Browser.PHANTOMJS); } @Override diff --git a/uitest/src/com/vaadin/tests/components/uitest/UIScrollingTest.java b/uitest/src/com/vaadin/tests/components/uitest/UIScrollingTest.java index 46d79a2ce5..cf6a6ac821 100644 --- a/uitest/src/com/vaadin/tests/components/uitest/UIScrollingTest.java +++ b/uitest/src/com/vaadin/tests/components/uitest/UIScrollingTest.java @@ -22,7 +22,6 @@ import java.util.List; import org.junit.Test; import org.openqa.selenium.By; -import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebElement; import com.vaadin.testbench.elements.ButtonElement; @@ -58,10 +57,7 @@ public class UIScrollingTest extends MultiBrowserTest { notification.findElement(By.tagName("h1")).getText()); // attempt to close the notification - try { - notification.closeNotification(); - } catch (StaleElementReferenceException e) { - } + notification.close(); WebElement ui = findElement(By.className("v-ui")); testBenchElement(ui).scroll(1020); @@ -74,9 +70,7 @@ public class UIScrollingTest extends MultiBrowserTest { assertEquals("Scrolled to 1020 px", notification.findElement(By.tagName("h1")).getText()); - try { - notification.closeNotification(); - } catch (StaleElementReferenceException e) { - } + notification.close(); + } } diff --git a/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java b/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java index ae966a5b07..f1d5432344 100644 --- a/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java +++ b/uitest/src/com/vaadin/tests/components/upload/TestFileUploadTest.java @@ -41,9 +41,7 @@ public class TestFileUploadTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { // PhantomJS fails to upload files for unknown reasons - List<DesiredCapabilities> b = super.getBrowsersToTest(); - b.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return b; + return getBrowsersExcludingPhantomJS(); } @Test diff --git a/uitest/src/com/vaadin/tests/components/window/CloseShortcutTest.java b/uitest/src/com/vaadin/tests/components/window/CloseShortcutTest.java index 7cca2ce4d0..df7b7cad0c 100644 --- a/uitest/src/com/vaadin/tests/components/window/CloseShortcutTest.java +++ b/uitest/src/com/vaadin/tests/components/window/CloseShortcutTest.java @@ -24,11 +24,13 @@ import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.WebDriver; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.elements.CheckBoxElement; import com.vaadin.testbench.elements.TextFieldElement; import com.vaadin.testbench.elements.WindowElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; /** @@ -101,12 +103,9 @@ public class CloseShortcutTest extends MultiBrowserTest { public void testOtherWithAll() { attemptOtherShortcut(); // TODO: remove this check once #14902 has been fixed - if (!Browser.IE8.getDesiredCapabilities().equals( - getDesiredCapabilities()) - && !Browser.FIREFOX.getDesiredCapabilities().equals( - getDesiredCapabilities()) - && !Browser.CHROME.getDesiredCapabilities().equals( - getDesiredCapabilities())) { + DesiredCapabilities cap = getDesiredCapabilities(); + if ((BrowserUtil.isIE(cap) && !BrowserUtil.isIE8(cap)) + || BrowserUtil.isPhantomJS(cap)) { ensureWindowClosed(); } } @@ -123,8 +122,7 @@ public class CloseShortcutTest extends MultiBrowserTest { public void testCtrlWithAll() { attemptCtrlShortcut(); // TODO: remove this check once #14902 has been fixed - if (Browser.PHANTOMJS.getDesiredCapabilities().equals( - getDesiredCapabilities())) { + if (BrowserUtil.isPhantomJS(getDesiredCapabilities())) { ensureWindowClosed(); } } @@ -141,9 +139,8 @@ public class CloseShortcutTest extends MultiBrowserTest { public void testShiftWithAll() { attemptShiftShortcut(); // TODO: remove this check once #14902 has been fixed - if (getBrowsersExcludingIE().contains(getDesiredCapabilities()) - || Browser.IE8.getDesiredCapabilities().equals( - getDesiredCapabilities())) { + DesiredCapabilities capabilities = getDesiredCapabilities(); + if (!BrowserUtil.isIE(capabilities) || BrowserUtil.isIE8(capabilities)) { ensureWindowClosed(); } } diff --git a/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java b/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java index 627efdc5b3..a80938ba32 100644 --- a/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java +++ b/uitest/src/com/vaadin/tests/components/window/ComboboxScrollableWindowTest.java @@ -24,10 +24,12 @@ import org.openqa.selenium.WebElement; import com.vaadin.testbench.By; import com.vaadin.testbench.commands.TestBenchElementCommands; import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.ComboBoxElement; +import com.vaadin.tests.tb3.newelements.WindowElement; /** + * Tests that a ComboBox at the bottom of a Window remains visible when clicked. * - * @since * @author Vaadin Ltd */ public class ComboboxScrollableWindowTest extends MultiBrowserTest { @@ -36,20 +38,16 @@ public class ComboboxScrollableWindowTest extends MultiBrowserTest { public void testWindowScrollbars() throws Exception { openTestURL(); - WebElement window = driver.findElement(By.id(WINDOW_ID)); + WindowElement window = $(WindowElement.class).id(WINDOW_ID); WebElement scrollableElement = window.findElement(By .className("v-scrollable")); TestBenchElementCommands scrollable = testBenchElement(scrollableElement); scrollable.scroll(1000); - WebElement comboBox = driver.findElement(By.id(COMBOBOX_ID)); - WebElement selectButton = driver.findElement(By - .className("v-filterselect-button")); - selectButton.click(); - - // Wait for the browser before taking a screenshot - Thread.sleep(1000); - compareScreen(getScreenshotBaseName()); + ComboBoxElement comboBox = $(ComboBoxElement.class).id(COMBOBOX_ID); + comboBox.openPopup(); + waitForElementPresent(By.className("v-filterselect-suggestpopup")); + compareScreen("combobox-open"); } } diff --git a/uitest/src/com/vaadin/tests/components/window/ModalWindowInitialLocation.java b/uitest/src/com/vaadin/tests/components/window/ModalWindowInitialLocation.java new file mode 100644 index 0000000000..3fa3730104 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/ModalWindowInitialLocation.java @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.window; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.ListSelect; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; + +public class ModalWindowInitialLocation extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + final Window w = new Window(); + VerticalLayout layout = new VerticalLayout(); + // Add lots of contents so that it is easier to see whether the + // window first appears in the wrong location. + for (int i = 0; i < 50; i++) { + final ListSelect listSelect = new ListSelect("Choose options"); + listSelect.setRows(4); + listSelect.setWidth("100%"); + listSelect.setImmediate(true); + listSelect.setMultiSelect(true); + listSelect.setNullSelectionAllowed(true); + listSelect.addItem(new String("Planning")); + listSelect.addItem(new String("Executing")); + listSelect.addItem(new String("Listing")); + listSelect.addItem(new String("Thinking")); + listSelect.addItem(new String("Sorting")); + listSelect.addItem(new String("Ordering")); + listSelect.select("Planning"); + listSelect.select("Ordering"); + layout.addComponent(listSelect); + } + + w.setCaption("Person Form"); + w.setWidth("400px"); + w.setHeight("400px"); + w.setContent(layout); + + Button b = new Button("Open window"); + b.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + w.setModal(true); + getUI().addWindow(w); + } + }); + addComponent(b); + } + + @Override + public String getTestDescription() { + return "When the button is clicked, a window should appear in the center of the browser window without " + + "flashing first in the upper left corner."; + } + + @Override + public Integer getTicketNumber() { + return 16486; + } +} diff --git a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java index 335590437d..e0cc240d6d 100644 --- a/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java +++ b/uitest/src/com/vaadin/tests/components/window/SubWindowsTextSelectionTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.components.window; -import java.util.ArrayList; import java.util.List; import org.junit.Assert; @@ -27,6 +26,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; /** @@ -48,18 +48,9 @@ public class SubWindowsTextSelectionTest extends MultiBrowserTest { return SubWindows.class; } - /* - * (non-Javadoc) - * - * @see com.vaadin.tests.tb3.MultiBrowserTest#getBrowsersToTest() - */ @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)); - return list; + return getBrowserCapabilities(Browser.IE9, Browser.IE10, Browser.IE11); } @Test diff --git a/uitest/src/com/vaadin/tests/components/window/WindowBGColorChameleonIE8Test.java b/uitest/src/com/vaadin/tests/components/window/WindowBGColorChameleonIE8Test.java index 18cb012cb2..4e9bffe3e8 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowBGColorChameleonIE8Test.java +++ b/uitest/src/com/vaadin/tests/components/window/WindowBGColorChameleonIE8Test.java @@ -7,7 +7,7 @@ import java.util.List; import org.junit.Test; import org.openqa.selenium.remote.DesiredCapabilities; -import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.testbench.parallel.Browser; import com.vaadin.tests.tb3.SingleBrowserTest; public class WindowBGColorChameleonIE8Test extends SingleBrowserTest { @@ -19,9 +19,7 @@ public class WindowBGColorChameleonIE8Test extends SingleBrowserTest { */ @Override public List<DesiredCapabilities> getBrowsersToTest() { - - return Arrays.asList(MultiBrowserTest.Browser.IE8 - .getDesiredCapabilities()); + return Arrays.asList(Browser.IE8.getDesiredCapabilities()); } @Test diff --git a/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java b/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java index 0bd6c9fa44..3cc310eeb4 100644 --- a/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java +++ b/uitest/src/com/vaadin/tests/components/window/WindowShadowTest.java @@ -17,7 +17,6 @@ package com.vaadin.tests.components.window; import java.awt.AWTException; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import org.junit.Test; @@ -61,9 +60,6 @@ public class WindowShadowTest extends MultiBrowserTest { // ignore this browser in testing @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - getAllBrowsers()); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - return browsers; + return getBrowsersExcludingIE8(); } }
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java index 90ea645ab8..d0eee99009 100644 --- a/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java +++ b/uitest/src/com/vaadin/tests/debug/PushVersionInfoTest.java @@ -24,7 +24,7 @@ import org.openqa.selenium.Keys; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; /** diff --git a/uitest/src/com/vaadin/tests/extensions/SetThemeAndResponsiveLayoutTest.java b/uitest/src/com/vaadin/tests/extensions/SetThemeAndResponsiveLayoutTest.java index 8a1fbde245..0d0b388541 100644 --- a/uitest/src/com/vaadin/tests/extensions/SetThemeAndResponsiveLayoutTest.java +++ b/uitest/src/com/vaadin/tests/extensions/SetThemeAndResponsiveLayoutTest.java @@ -43,7 +43,7 @@ public class SetThemeAndResponsiveLayoutTest extends MultiBrowserTest { public List<DesiredCapabilities> getBrowsersToTest() { // Seems like stylesheet onload is not fired on PhantomJS // https://github.com/ariya/phantomjs/issues/12332 - return super.getBrowsersExcludingPhantomJS(); + return getBrowsersExcludingPhantomJS(); } @Test diff --git a/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRowTest.java b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRowTest.java index bdf8603c48..7b18053052 100644 --- a/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRowTest.java +++ b/uitest/src/com/vaadin/tests/fieldgroup/BasicCrudGridEditorRowTest.java @@ -27,7 +27,7 @@ import com.vaadin.testbench.elements.DateFieldElement; import com.vaadin.testbench.elements.GridElement; import com.vaadin.testbench.elements.GridElement.GridCellElement; import com.vaadin.testbench.elements.GridElement.GridEditorElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("grid") diff --git a/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java b/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java index 948c3c13b2..4cfcd8fa59 100644 --- a/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java +++ b/uitest/src/com/vaadin/tests/fonticon/FontIconsTest.java @@ -20,11 +20,10 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; import org.junit.Test; -import org.openqa.selenium.By; import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.tb3.newelements.ComboBoxElement; public class FontIconsTest extends MultiBrowserTest { @@ -37,29 +36,21 @@ public class FontIconsTest extends MultiBrowserTest { @Test public void comboBoxItemIconsOnKeyboardNavigation() throws Exception { openTestURL(); - WebElement comboBoxInput = getDriver().findElement( - By.className("v-filterselect-input")); + + ComboBoxElement comboBox = $(ComboBoxElement.class).first(); // No initial value. - assertEquals("", comboBoxInput.getText()); + assertEquals("", comboBox.getText()); // Navigate to the first item with keyboard navigation. - sendKeys(comboBoxInput, Keys.ARROW_DOWN, Keys.ARROW_DOWN, - Keys.ARROW_DOWN); + comboBox.sendKeys(400, Keys.ARROW_DOWN, Keys.ARROW_DOWN); // Value must be "One" without any extra characters. // See ticket #14660 - assertEquals("One", comboBoxInput.getAttribute("value")); + assertEquals("One", comboBox.getText()); // Check also the second item. - sendKeys(comboBoxInput, Keys.ARROW_DOWN); - assertEquals("Two", comboBoxInput.getAttribute("value")); - } - - private void sendKeys(WebElement element, Keys... keys) throws Exception { - for (Keys key : keys) { - element.sendKeys(key); - sleep(10); // For PhantomJS. - } + comboBox.sendKeys(Keys.ARROW_DOWN); + assertEquals("Two", comboBox.getText()); } } diff --git a/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java b/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java index 073975a509..5dd59a8245 100644 --- a/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java +++ b/uitest/src/com/vaadin/tests/integration/AbstractIntegrationTest.java @@ -15,8 +15,8 @@ */ 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 diff --git a/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java b/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java index 941e988c5c..7e9a2138e4 100644 --- a/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java +++ b/uitest/src/com/vaadin/tests/integration/AbstractServletIntegrationTest.java @@ -39,8 +39,8 @@ public abstract class AbstractServletIntegrationTest extends } @Override - protected String getDeploymentPath() { - return "/demo" + super.getDeploymentPath(); + protected String getDeploymentPath(Class<?> uiClass) { + return "/demo" + super.getDeploymentPath(uiClass); } } diff --git a/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java b/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java index bfe38b8865..33adb622c0 100644 --- a/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java +++ b/uitest/src/com/vaadin/tests/layouts/IE8MeasuredSizeMemoryLeakTest.java @@ -15,7 +15,6 @@ */ package com.vaadin.tests.layouts; -import java.util.Collections; import java.util.List; import org.junit.Assert; @@ -23,6 +22,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 { @@ -49,6 +49,6 @@ public class IE8MeasuredSizeMemoryLeakTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - return Collections.singletonList(Browser.IE8.getDesiredCapabilities()); + return getBrowserCapabilities(Browser.IE8); } } diff --git a/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java b/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java index 4013494c49..7bd1de5803 100644 --- a/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java +++ b/uitest/src/com/vaadin/tests/push/BarInUIDLTest.java @@ -19,7 +19,7 @@ import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.WebElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/BasicPushTest.java b/uitest/src/com/vaadin/tests/push/BasicPushTest.java index fd34a1f192..5bac54f0f7 100644 --- a/uitest/src/com/vaadin/tests/push/BasicPushTest.java +++ b/uitest/src/com/vaadin/tests/push/BasicPushTest.java @@ -20,7 +20,7 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.AbstractTB3Test; import com.vaadin.tests.tb3.MultiBrowserTest; diff --git a/uitest/src/com/vaadin/tests/push/EnableDisablePushTest.java b/uitest/src/com/vaadin/tests/push/EnableDisablePushTest.java index 03b34655a1..654108f8f9 100644 --- a/uitest/src/com/vaadin/tests/push/EnableDisablePushTest.java +++ b/uitest/src/com/vaadin/tests/push/EnableDisablePushTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; import org.openqa.selenium.WebElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java b/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java index 4b142500f7..344f551f00 100644 --- a/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java +++ b/uitest/src/com/vaadin/tests/push/IdlePushChannelTest.java @@ -18,7 +18,7 @@ package com.vaadin.tests.push; import org.junit.Assert; import org.junit.Test; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java index 396160cc7d..14ef9e1144 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationTest.java @@ -22,26 +22,26 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; import com.vaadin.testbench.elements.NativeSelectElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") abstract class PushConfigurationTest extends MultiBrowserTest { @Override + protected Class<?> getUIClass() { + return PushConfiguration.class; + } + + @Override public void setup() throws Exception { super.setup(); + setDebug(true); - openTestURL(); + openTestURL("restartApplication"); disablePush(); } - @Override - protected String getDeploymentPath() { - return "/run/" + PushConfiguration.class.getCanonicalName() - + "?restartApplication&debug"; - } - protected String getStatusText() { WebElement statusLabel = vaadinElementById("status"); diff --git a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java index 475fa2165f..501d946fcc 100644 --- a/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java +++ b/uitest/src/com/vaadin/tests/push/PushConfigurationWebSocketTest.java @@ -28,13 +28,7 @@ public class PushConfigurationWebSocketTest extends PushConfigurationTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - browsers.remove(Browser.IE8.getDesiredCapabilities()); - browsers.remove(Browser.IE9.getDesiredCapabilities()); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - - return browsers; + return getBrowsersSupportingWebSocket(); } @Test diff --git a/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java b/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java index 1f6e181c89..2683868db5 100644 --- a/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushErrorHandlingTest.java @@ -21,7 +21,8 @@ import org.openqa.selenium.By; import org.openqa.selenium.WebElement; import com.vaadin.testbench.elements.LabelElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.BrowserUtil; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/PushFromInitTest.java b/uitest/src/com/vaadin/tests/push/PushFromInitTest.java index a285d91e92..fe7ebebef1 100644 --- a/uitest/src/com/vaadin/tests/push/PushFromInitTest.java +++ b/uitest/src/com/vaadin/tests/push/PushFromInitTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java index e37bd32832..23255aadea 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataLongPollingTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java index 058ac6cc92..0c00cf116f 100644 --- a/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java +++ b/uitest/src/com/vaadin/tests/push/PushLargeDataStreamingTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.support.ui.ExpectedConditions; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/PushPath.java b/uitest/src/com/vaadin/tests/push/PushPath.java new file mode 100644 index 0000000000..20771bd84f --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushPath.java @@ -0,0 +1,77 @@ +/* + * 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 com.vaadin.annotations.Push; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ui.Transport; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Label; + +@Push(transport = Transport.WEBSOCKET) +public class PushPath extends AbstractTestUI { + + public static final String PUSH_PATH_LABEL_ID = "push-path-label-id"; + public static final String PUSH_PATH_LABEL_TEXT = "Label by push"; + + @Override + protected void setup(VaadinRequest request) { + // use only websockets + getPushConfiguration().setFallbackTransport(Transport.WEBSOCKET); + + String pushPath = request.getService().getDeploymentConfiguration() + .getPushPath(); + String transport = getPushConfiguration().getTransport().name(); + Label pushPathLabel = new Label(String.format( + "Waiting for push from path '%s' using %s in 3 seconds.", + pushPath, transport)); + addComponent(pushPathLabel); + + new PushThread().start(); + } + + public class PushThread extends Thread { + + @Override + public void run() { + try { + Thread.sleep(3000); + } catch (InterruptedException e) { + } + access(new Runnable() { + + @Override + public void run() { + Label pushLabel = new Label(PUSH_PATH_LABEL_TEXT); + pushLabel.setId(PUSH_PATH_LABEL_ID); + addComponent(pushLabel); + } + }); + + } + } + + @Override + public Integer getTicketNumber() { + return 14432; + } + + @Override + public String getDescription() { + return "Push path should be configurable since some servers can't serve both websockets and long polling from same URL."; + } + +} diff --git a/uitest/src/com/vaadin/tests/push/PushPathTest.java b/uitest/src/com/vaadin/tests/push/PushPathTest.java new file mode 100644 index 0000000000..0af9c8d3a7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushPathTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.push; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.tb3.WebsocketTest; + +public class PushPathTest extends WebsocketTest { + + private static final int TEN_SECONDS_IN_MS = 10 * 1000; + + @Test + public void testCustomPushPath() throws InterruptedException { + openTestURL(); + sleep(TEN_SECONDS_IN_MS); + Assert.assertEquals(vaadinElementById(PushPath.PUSH_PATH_LABEL_ID) + .getText(), PushPath.PUSH_PATH_LABEL_TEXT); + } + + @Override + protected String getDeploymentPath(Class<?> uiClass) { + return "/run-pushpath/" + uiClass.getCanonicalName(); + } +} diff --git a/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java index 42babb00d0..47773b87b6 100644 --- a/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java +++ b/uitest/src/com/vaadin/tests/push/RefreshCloseConnectionTest.java @@ -17,13 +17,12 @@ package com.vaadin.tests.push; import java.util.List; -import com.vaadin.tests.annotations.TestCategory; import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.remote.DesiredCapabilities; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; -import com.vaadin.tests.tb3.WebsocketTest; @TestCategory("push") public class RefreshCloseConnectionTest extends MultiBrowserTest { diff --git a/uitest/src/com/vaadin/tests/push/SendMultibyteCharactersTest.java b/uitest/src/com/vaadin/tests/push/SendMultibyteCharactersTest.java index a639f7dbe3..69e5de960a 100644 --- a/uitest/src/com/vaadin/tests/push/SendMultibyteCharactersTest.java +++ b/uitest/src/com/vaadin/tests/push/SendMultibyteCharactersTest.java @@ -1,10 +1,11 @@ package com.vaadin.tests.push; +import org.junit.Test; + import com.vaadin.testbench.By; import com.vaadin.testbench.elements.TextAreaElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; -import org.junit.Test; @TestCategory("push") public abstract class SendMultibyteCharactersTest extends MultiBrowserTest { diff --git a/uitest/src/com/vaadin/tests/push/TogglePushTest.java b/uitest/src/com/vaadin/tests/push/TogglePushTest.java index 3ca12fdd84..d93802125c 100644 --- a/uitest/src/com/vaadin/tests/push/TogglePushTest.java +++ b/uitest/src/com/vaadin/tests/push/TogglePushTest.java @@ -19,7 +19,7 @@ import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.WebElement; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java index b4af11b864..35d0f0ad5f 100644 --- a/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java +++ b/uitest/src/com/vaadin/tests/push/TrackMessageSizeUITest.java @@ -18,7 +18,7 @@ package com.vaadin.tests.push; import org.junit.Assert; import org.junit.Test; -import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.testbench.parallel.TestCategory; import com.vaadin.tests.tb3.MultiBrowserTest; @TestCategory("push") diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index cd89579c31..ef32d9a067 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -16,43 +16,36 @@ package com.vaadin.tests.tb3; -import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; - import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; import java.lang.reflect.Field; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.NoSuchElementException; +import java.util.Set; 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.After; -import org.junit.Before; 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.ie.InternetExplorerDriver; import org.openqa.selenium.interactions.HasInputDevices; 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; @@ -60,20 +53,21 @@ 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.TestBenchDriverProxy; import com.vaadin.testbench.TestBenchElement; -import com.vaadin.testbench.TestBenchTestCase; -import com.vaadin.testbench.elements.AbstractElement; +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; @@ -95,8 +89,8 @@ import elemental.json.impl.JsonUtil; * * @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(); @@ -116,17 +110,9 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { */ private static final int BROWSER_TIMEOUT_IN_MS = 30 * 1000; - private static final int BROWSER_INIT_ATTEMPTS = 5; - - 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 @@ -139,61 +125,14 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * * @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(); - - for (int i = 1; i <= BROWSER_INIT_ATTEMPTS; i++) { - try { - if (localWebDriverIsUsed()) { - setupLocalDriver(capabilities); - } else { - setupRemoteDriver(capabilities); - } - break; - } catch (Exception e) { - System.err - .println("Browser startup for " + capabilities - + " failed on attempt " + i + ": " - + e.getMessage()); - if (i == BROWSER_INIT_ATTEMPTS) { - throw e; - } - } - } - - } + 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; @@ -206,12 +145,16 @@ 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(); + } } } @@ -274,54 +217,13 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { waitUntilRowIsVisible(table, rowToWait); } - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface RunLocally { - public Browser value() default Browser.FIREFOX; - } - - /** - * 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); - - /** - * Creates a {@link WebDriver} instance used for running the test remotely. - * - * @since - * @param capabilities - * the type of browser needed - * @throws Exception - */ - private void setupRemoteDriver(DesiredCapabilities capabilities) - throws Exception { - if (BrowserUtil.isIE(capabilities)) { - if (requireWindowFocusForIE()) { - capabilities.setCapability( - InternetExplorerDriver.REQUIRE_WINDOW_FOCUS, true); - } - if (!usePersistentHoverForIE()) { - capabilities.setCapability( - InternetExplorerDriver.ENABLE_PERSISTENT_HOVERING, - false); - } - } - - WebDriver dr = TestBench.createDriver(new RemoteWebDriver(new URL( - getHubURL()), capabilities)); - setDriver(dr); - } - /** * 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() { - openTestURL(""); + protected void openTestURL(String... parameters) { + openTestURL(getUIClass(), parameters); } /** @@ -329,13 +231,25 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * debug window and/or push (depending on {@link #isDebug()} and * {@link #isPush()}. */ - protected void openTestURL(String extraParameters) { - String url = getTestUrl(); - if (url.contains("?")) { - url = url + "&" + extraParameters; - } else { - url = url + "?" + extraParameters; + protected void openTestURL(Class<?> uiClass, String... parameters) { + openTestURL(uiClass, new HashSet<String>(Arrays.asList(parameters))); + } + + private void openTestURL(Class<?> uiClass, Set<String> parameters) { + String url = getTestURL(uiClass); + + if(isDebug()) { + parameters.add("debug"); + } + + if (LegacyApplication.class.isAssignableFrom(uiClass)) { + parameters.add("restartApplication"); } + + if (parameters.size() > 0) { + url += "?" + Joiner.on("&").join(parameters); + } + driver.get(url); } @@ -345,30 +259,20 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * @return the full URL for the test */ protected String getTestUrl() { - String baseUrl = getBaseURL(); - if (baseUrl.endsWith("/")) { - baseUrl = baseUrl.substring(0, baseUrl.length() - 1); - } - - return baseUrl + getDeploymentPath(); + return StringUtils.strip(getBaseURL(), "/") + getDeploymentPath(); } /** + * Returns the full URL to be used for the test for the provided UI class. * - * @return the location (URL) of the TB hub + * @return the full URL for the test */ - protected String getHubURL() { - return "http://" + getHubHostname() + ":4444/wd/hub"; + protected String getTestURL(Class<?> uiClass) { + return StringUtils.strip(getBaseURL(), "/") + + getDeploymentPath(uiClass); } /** - * Used for building the hub URL to use for the test - * - * @return the host name of the TestBench hub - */ - protected abstract String getHubHostname(); - - /** * Used to determine what URL to initially open for the test * * @return the host name of development server @@ -395,55 +299,13 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * * @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) { - // Make a copy as the desired capabilities can come from a shared, - // static resource. This will cause all kinds of problems if some test - // modifies the capabilities - this.desiredCapabilities = new DesiredCapabilities(desiredCapabilities); - } - - /** - * Shuts down the driver after the test has been completed - * - * @throws Exception - */ - @After - public void tearDown() throws Exception { - if (driver != null) { - try { - openTestURL("&closeApplication"); - } catch (Exception e) { - e.printStackTrace(); - } - 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]). @@ -833,19 +695,16 @@ 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) - || UIProvider.class.isAssignableFrom(uiClass)) { - return runPath + "/" + uiClass.getCanonicalName() - + (isDebug() ? "?debug" : ""); - } else if (LegacyApplication.class.isAssignableFrom(uiClass)) { - return runPath + "/" + uiClass.getCanonicalName() - + "?restartApplication" + (isDebug() ? "&debug" : ""); + || UIProvider.class.isAssignableFrom(uiClass) + || LegacyApplication.class.isAssignableFrom(uiClass)) { + return runPath + "/" + uiClass.getCanonicalName(); } else { throw new IllegalArgumentException( "Unable to determine path for enclosing class " @@ -903,264 +762,6 @@ 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.VISTA); - 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); - c.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, - true); - 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 - * @param version - * @return true if the capabilities refer to IE8, false otherwise - */ - public static boolean isIE8(DesiredCapabilities capabilities) { - return isIE(8, capabilities); - } - - /** - * Checks if the given capabilities refer to Internet Explorer of the - * given version - * - * @param capabilities - * @param version - * @return true if the capabilities refer to IE of the given version, - * false otherwise - */ - public static boolean isIE(int version, DesiredCapabilities capabilities) { - return isIE(capabilities) - && ("" + version).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 * @@ -1332,17 +933,4 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { protected void click(CheckBoxElement checkbox) { checkbox.findElement(By.xpath("input")).click(); } - - @Override - public boolean isElementPresent(Class<? extends AbstractElement> clazz) { - // This is a bug in TB4 as isElementPresent(..) should just return true - // or false but can also throw exceptions. The problem is possibly if - // this is run when the Vaadin app is not initialized yet - try { - return super.isElementPresent(clazz); - } catch (NoSuchElementException e) { - return false; - } - } - } diff --git a/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java index 6736bc3990..128214de1e 100644 --- a/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java +++ b/uitest/src/com/vaadin/tests/tb3/AffectedTB3Tests.java @@ -1,5 +1,7 @@ package com.vaadin.tests.tb3; +import java.io.IOException; + import org.junit.runner.RunWith; import org.junit.runners.model.InitializationError; @@ -18,7 +20,8 @@ public class AffectedTB3Tests { public static class AffectedTB3TestSuite extends TB3TestSuite { - public AffectedTB3TestSuite(Class<?> klass) throws InitializationError { + public AffectedTB3TestSuite(Class<?> klass) throws InitializationError, + IOException { super(klass, AbstractTB3Test.class, "com.vaadin.tests", new String[] { "com.vaadin.tests.integration" }, new AffectedTB3TestLocator()); diff --git a/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java index b7cc8284d1..338855ba1c 100644 --- a/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java +++ b/uitest/src/com/vaadin/tests/tb3/AllTB3Tests.java @@ -16,6 +16,8 @@ package com.vaadin.tests.tb3; +import java.io.IOException; + import org.junit.runner.RunWith; import org.junit.runners.model.InitializationError; @@ -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/ChangedTB3Tests.java b/uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java index 2200566b84..3c7030b1e9 100644 --- a/uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java +++ b/uitest/src/com/vaadin/tests/tb3/ChangedTB3Tests.java @@ -15,6 +15,8 @@ */ package com.vaadin.tests.tb3; +import java.io.IOException; + import org.junit.runner.RunWith; import org.junit.runners.model.InitializationError; @@ -31,7 +33,8 @@ import com.vaadin.tests.tb3.ChangedTB3Tests.ChangedTB3TestsSuite; @RunWith(ChangedTB3TestsSuite.class) public class ChangedTB3Tests { public static class ChangedTB3TestsSuite extends TB3TestSuite { - public ChangedTB3TestsSuite(Class<?> klass) throws InitializationError { + 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/DndActionsTest.java b/uitest/src/com/vaadin/tests/tb3/DndActionsTest.java index 96a2280323..71d6b6fab4 100644 --- a/uitest/src/com/vaadin/tests/tb3/DndActionsTest.java +++ b/uitest/src/com/vaadin/tests/tb3/DndActionsTest.java @@ -19,6 +19,8 @@ import org.junit.Ignore; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; +import com.vaadin.testbench.parallel.BrowserUtil; + /** * Base class for TestBench 3+ tests that use DnD. This class contains utility * methods for DnD operations. diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java index 19f62d69ee..b166590c43 100644 --- a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java +++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTest.java @@ -17,11 +17,17 @@ package com.vaadin.tests.tb3; import java.util.ArrayList; -import java.util.Collections; +import java.util.Calendar; import java.util.List; +import org.junit.Rule; +import org.junit.rules.TestName; +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 @@ -40,101 +46,77 @@ import org.openqa.selenium.remote.DesiredCapabilities; */ public abstract class MultiBrowserTest extends PrivateTB3Configuration { - protected List<DesiredCapabilities> getBrowsersSupportingWebSocket() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - getAllBrowsers()); - - browsers.remove(Browser.IE8.getDesiredCapabilities()); - browsers.remove(Browser.IE9.getDesiredCapabilities()); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); + @Rule + public TestName testName = new TestName(); - return browsers; + protected List<DesiredCapabilities> getBrowsersSupportingWebSocket() { + // No WebSocket support in IE8-9 and PhantomJS + return getBrowserCapabilities(Browser.IE10, Browser.IE11, + Browser.FIREFOX, Browser.CHROME); } protected List<DesiredCapabilities> getBrowsersExcludingPhantomJS() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - getAllBrowsers()); - - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - - return browsers; + return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10, + Browser.IE11, Browser.CHROME, Browser.FIREFOX); } 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()); - - return browsers; + return getBrowserCapabilities(Browser.FIREFOX, Browser.CHROME, + Browser.PHANTOMJS); } - protected List<DesiredCapabilities> getBrowsersSupportingShiftClick() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>( - getAllBrowsers()); - - // IE supports shift click only when require window focus is true - browsers.remove(Browser.FIREFOX.getDesiredCapabilities()); - browsers.remove(Browser.PHANTOMJS.getDesiredCapabilities()); + protected List<DesiredCapabilities> getBrowsersExcludingIE8() { + return getBrowserCapabilities(Browser.IE9, Browser.IE10, Browser.IE11, + Browser.FIREFOX, Browser.CHROME, Browser.PHANTOMJS); + } - return browsers; + protected List<DesiredCapabilities> getBrowsersSupportingShiftClick() { + return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10, + Browser.IE11, Browser.CHROME); } protected List<DesiredCapabilities> getIEBrowsersOnly() { - List<DesiredCapabilities> browsers = new ArrayList<DesiredCapabilities>(); - browsers.add(Browser.IE8.getDesiredCapabilities()); - browsers.add(Browser.IE9.getDesiredCapabilities()); - browsers.add(Browser.IE10.getDesiredCapabilities()); - browsers.add(Browser.IE11.getDesiredCapabilities()); - - return browsers; + return getBrowserCapabilities(Browser.IE8, Browser.IE9, Browser.IE10, + Browser.IE11); } - public enum Browser { - FIREFOX(BrowserUtil.firefox(24)), CHROME(BrowserUtil.chrome(40)), 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; - - private Browser(DesiredCapabilities desiredCapabilities) { - this.desiredCapabilities = desiredCapabilities; + @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); + } } - public DesiredCapabilities getDesiredCapabilities() { - return desiredCapabilities; - } - } + desiredCapabilities.setCapability("project", "Vaadin Framework"); + desiredCapabilities.setCapability("build", String.format("%s / %s", + getDeploymentHostname(), Calendar.getInstance().getTime())); + desiredCapabilities.setCapability("name", String.format("%s.%s", + getClass().getCanonicalName(), testName.getMethodName())); - 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()); - } - - /** - * @return all supported browsers which are actively tested - */ - public static List<DesiredCapabilities> getAllBrowsers() { - return Collections.unmodifiableList(allBrowsers); + 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..f8b01fb11b 100755 --- a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java +++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java @@ -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 32d0f1065c..8f8e446ce3 100644 --- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java +++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java @@ -22,21 +22,11 @@ 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.chrome.ChromeOptions; -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. @@ -45,6 +35,8 @@ import com.vaadin.tests.tb3.MultiBrowserTest.Browser; * * @author Vaadin Ltd */ +@RunOnHub("tb3-hub.intra.itmill.com") +@BrowserFactory(VaadinBrowserFactory.class) public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { /** * @@ -54,6 +46,7 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { 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"); @@ -98,8 +91,13 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { } @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 @@ -192,81 +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); - - // Tells chrome not to show warning - // "You are using an unsupported command-line flag: --ignore-certifcate-errors". - // #14319 - ChromeOptions options = new ChromeOptions(); - options.addArguments("--test-type "); - driver = new ChromeDriver(options); - } 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 4a4354d67c..f401e0613b 100644 --- a/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java @@ -16,32 +16,26 @@ 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.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import javax.imageio.ImageIO; - import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; 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 @@ -51,6 +45,29 @@ import com.vaadin.testbench.commands.TestBenchCommands; */ 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 @@ -331,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"; } /** @@ -409,10 +393,9 @@ 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); } @@ -423,6 +406,40 @@ public abstract class ScreenshotTB3Test extends AbstractTB3Test { } /** + * 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 diff --git a/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java b/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java index 294d012be5..77c5676215 100644 --- a/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java +++ b/uitest/src/com/vaadin/tests/tb3/ServletIntegrationTests.java @@ -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 index f5dc337138..960d6b8777 100644 --- a/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java +++ b/uitest/src/com/vaadin/tests/tb3/SingleBrowserTest.java @@ -20,12 +20,12 @@ 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.unmodifiableList(Collections - .singletonList(MultiBrowserTest.Browser.PHANTOMJS - .getDesiredCapabilities())); + return Collections.singletonList(Browser.PHANTOMJS + .getDesiredCapabilities()); } - } diff --git a/uitest/src/com/vaadin/tests/tb3/TB3Runner.java b/uitest/src/com/vaadin/tests/tb3/TB3Runner.java index 0d540644bf..acdef54492 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,7 +35,7 @@ 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 @@ -62,24 +44,7 @@ public class TB3Runner extends BlockJUnit4ClassRunner { */ private static final int SOCKET_TIMEOUT = 30 * 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; - static { - if (localWebDriverIsUsed()) { - 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/TB3TestSuite.java b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java index b0554ce0f6..c68d59a4eb 100644 --- a/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java +++ b/uitest/src/com/vaadin/tests/tb3/TB3TestSuite.java @@ -16,46 +16,33 @@ package com.vaadin.tests.tb3; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.io.IOException; -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 { + String[] ignorePackages) throws InitializationError, IOException { this(klass, baseClass, basePackage, ignorePackages, new TB3TestLocator()); } public TB3TestSuite(Class<?> klass, Class<? extends AbstractTB3Test> baseClass, String basePackage, - String[] ignorePackages, TB3TestLocator testLocator) - throws InitializationError { - super(klass, testLocator.findTests(baseClass, basePackage, - ignorePackages)); - setScheduler(new ParallelScheduler(service)); + String[] ignorePackages, TB3TestLocator locator) + throws InitializationError, IOException { + super(klass, locator + .findClasses(baseClass, basePackage, ignorePackages).toArray( + new Class<?>[] {})); } } diff --git a/uitest/src/com/vaadin/tests/tb3/TestNameSuffix.java b/uitest/src/com/vaadin/tests/tb3/TestNameSuffix.java deleted file mode 100644 index 615cd8d5b7..0000000000 --- a/uitest/src/com/vaadin/tests/tb3/TestNameSuffix.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Defines a system property to be used as part of the test name - */ -@Retention(RetentionPolicy.RUNTIME) -public @interface TestNameSuffix { - - String property(); - -} 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..f55b434ee0 --- /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 7f65357a65..ee8cab22fd 100644 --- a/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java +++ b/uitest/src/com/vaadin/tests/tb3/WebsocketTest.java @@ -19,14 +19,11 @@ */ 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 @@ -39,7 +36,6 @@ public abstract class WebsocketTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - return new ArrayList<DesiredCapabilities>( - getBrowsersSupportingWebSocket()); + return getBrowsersSupportingWebSocket(); } } diff --git a/uitest/src/com/vaadin/tests/tb3/newelements/CalendarElement.java b/uitest/src/com/vaadin/tests/tb3/newelements/CalendarElement.java index e5213b21b5..40475afd3c 100644 --- a/uitest/src/com/vaadin/tests/tb3/newelements/CalendarElement.java +++ b/uitest/src/com/vaadin/tests/tb3/newelements/CalendarElement.java @@ -5,7 +5,7 @@ import java.util.List; import org.openqa.selenium.WebElement; import com.vaadin.testbench.By; -import com.vaadin.testbench.elements.ServerClass; +import com.vaadin.testbench.elementsbase.ServerClass; @ServerClass("com.vaadin.ui.Calendar") public class CalendarElement extends diff --git a/uitest/src/com/vaadin/tests/tb3/newelements/ComboBoxElement.java b/uitest/src/com/vaadin/tests/tb3/newelements/ComboBoxElement.java new file mode 100644 index 0000000000..6a0f164b13 --- /dev/null +++ b/uitest/src/com/vaadin/tests/tb3/newelements/ComboBoxElement.java @@ -0,0 +1,54 @@ +package com.vaadin.tests.tb3.newelements; + +import org.junit.Assert; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elementsbase.ServerClass; + +@ServerClass("com.vaadin.ui.ComboBox") +public class ComboBoxElement extends + com.vaadin.testbench.elements.ComboBoxElement { + + public WebElement getInputField() { + return findElement(By.vaadin("#textbox")); + } + + @Override + public String getText() { + return getInputField().getAttribute("value"); + } + + @Override + public void clear() { + getInputField().clear(); + } + + @Override + public void sendKeys(CharSequence... keysToSend) { + sendKeys(50, keysToSend); + } + + /** + * Use this method to simulate typing into an element, which may set its + * value. + * + * @param delay + * delay after sending each individual key (mainly needed for + * PhantomJS) + * @param keysToSend + * keys to type into the element + */ + public void sendKeys(int delay, CharSequence... keysToSend) { + WebElement input = getInputField(); + + for (CharSequence key : keysToSend) { + input.sendKeys(key); + try { + Thread.sleep(delay); + } catch (InterruptedException e) { + Assert.fail(e.getMessage()); + } + } + } +} diff --git a/uitest/src/com/vaadin/tests/tb3/newelements/FixedNotificationElement.java b/uitest/src/com/vaadin/tests/tb3/newelements/FixedNotificationElement.java index ff7715e281..a3eb952ea7 100644 --- a/uitest/src/com/vaadin/tests/tb3/newelements/FixedNotificationElement.java +++ b/uitest/src/com/vaadin/tests/tb3/newelements/FixedNotificationElement.java @@ -6,16 +6,18 @@ import org.openqa.selenium.support.ui.WebDriverWait; import com.vaadin.testbench.By; import com.vaadin.testbench.elements.NotificationElement; -import com.vaadin.testbench.elements.ServerClass; +import com.vaadin.testbench.elementsbase.ServerClass; @ServerClass("com.vaadin.ui.Notification") public class FixedNotificationElement extends NotificationElement { + @Override public String getCaption() { WebElement popup = findElement(By.className("popupContent")); WebElement caption = popup.findElement(By.tagName("h1")); return caption.getText(); } + @Override public void close() { click(); WebDriverWait wait = new WebDriverWait(getDriver(), 10); diff --git a/uitest/src/com/vaadin/tests/tb3/newelements/WindowElement.java b/uitest/src/com/vaadin/tests/tb3/newelements/WindowElement.java index 9e3433f1af..34344324d0 100644 --- a/uitest/src/com/vaadin/tests/tb3/newelements/WindowElement.java +++ b/uitest/src/com/vaadin/tests/tb3/newelements/WindowElement.java @@ -4,7 +4,7 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import com.vaadin.testbench.By; -import com.vaadin.testbench.elements.ServerClass; +import com.vaadin.testbench.elementsbase.ServerClass; /* Suggestions for new elemental api for Window @@ -59,6 +59,7 @@ public class WindowElement extends com.vaadin.testbench.elements.WindowElement { /** * @return the caption of the window */ + @Override public String getCaption() { return findElement(By.className("v-window-header")).getText(); } diff --git a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java index a5657c4eec..79da9f902d 100644 --- a/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java +++ b/uitest/src/com/vaadin/tests/themes/ThemeChangeOnTheFlyTest.java @@ -15,8 +15,12 @@ */ package com.vaadin.tests.themes; -import com.vaadin.testbench.elements.ButtonElement; -import com.vaadin.tests.tb3.MultiBrowserTest; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.io.IOException; +import java.util.List; + import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; @@ -24,11 +28,8 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.support.ui.ExpectedCondition; -import java.io.IOException; -import java.util.List; - -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.MatcherAssert.assertThat; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.tb3.MultiBrowserTest; public class ThemeChangeOnTheFlyTest extends MultiBrowserTest { @@ -36,9 +37,7 @@ public class ThemeChangeOnTheFlyTest extends MultiBrowserTest { public List<DesiredCapabilities> getBrowsersToTest() { // Seems like stylesheet onload is not fired on PhantomJS // https://github.com/ariya/phantomjs/issues/12332 - List<DesiredCapabilities> l = super.getBrowsersToTest(); - l.remove(Browser.PHANTOMJS.getDesiredCapabilities()); - return l; + return getBrowsersExcludingPhantomJS(); } @Test diff --git a/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java index 87827b1358..137b845e52 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ImmediateUploadTest.java @@ -19,12 +19,10 @@ import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import java.io.IOException; -import java.util.List; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; -import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.testbench.elements.UploadElement; import com.vaadin.tests.tb3.MultiBrowserTest; @@ -37,11 +35,6 @@ import com.vaadin.tests.tb3.MultiBrowserTest; public class ImmediateUploadTest extends MultiBrowserTest { @Override - public List<DesiredCapabilities> getBrowsersToTest() { - return getAllBrowsers(); - } - - @Override public void setup() throws Exception { super.setup(); openTestURL(); diff --git a/uitest/src/com/vaadin/tests/themes/valo/TextFieldBevelTest.java b/uitest/src/com/vaadin/tests/themes/valo/TextFieldBevelTest.java index 9159b71961..efe194d28a 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/TextFieldBevelTest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/TextFieldBevelTest.java @@ -36,12 +36,7 @@ public class TextFieldBevelTest extends MultiBrowserTest { @Override public List<DesiredCapabilities> getBrowsersToTest() { - List<DesiredCapabilities> browsers = super.getBrowsersToTest(); - - // IE8 doesn't support box-shadow. - browsers.remove(Browser.IE8.getDesiredCapabilities()); - - return browsers; + return getBrowsersExcludingIE8(); } @Test diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java index 13b0c7144c..3ab224f105 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java @@ -24,6 +24,7 @@ import com.vaadin.testbench.elements.CheckBoxElement; import com.vaadin.testbench.elements.CssLayoutElement; import com.vaadin.testbench.elements.LabelElement; import com.vaadin.testbench.elements.TreeElement; +import com.vaadin.testbench.parallel.BrowserUtil; import com.vaadin.tests.tb3.MultiBrowserTest; public class ValoThemeUITest extends MultiBrowserTest { diff --git a/uitest/src/com/vaadin/tests/widgetset/client/RunOverflowFixConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/RunOverflowFixConnector.java new file mode 100644 index 0000000000..a6789ebaf6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/RunOverflowFixConnector.java @@ -0,0 +1,137 @@ +package com.vaadin.tests.widgetset.client; + +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Panel; +import com.vaadin.client.ComponentConnector; +import com.vaadin.client.ConnectorHierarchyChangeEvent; +import com.vaadin.client.WidgetUtil; +import com.vaadin.client.ui.AbstractComponentContainerConnector; +import com.vaadin.client.ui.VVerticalLayout; +import com.vaadin.shared.ui.Connect; +import com.vaadin.shared.ui.orderedlayout.VerticalLayoutState; +import com.vaadin.tests.components.customlayout.OverflowAutoFix; + +@SuppressWarnings("deprecation") +@Connect(OverflowAutoFix.RunOverflowFix.class) +public class RunOverflowFixConnector extends + AbstractComponentContainerConnector { + + private static final String CONTENT1 = "Overflow:<br>Fix1 (scroll): Both scrollbars should be shown<br>Fix2 (visible): no scrollbars should be shown"; + private static final String CONTENT2 = "OverflowX:<br>Fix1 (hidden): Horizontal scrollbar should be hidden, vertical shown<br>Fix2 (scroll): Both scrollbars should be shown"; + private static final String CONTENT3 = "OverflowY:<br>Fix1 (hidden): Vertical scrollbar should be hidden, horizontal shown<br>Fix2 (auto): Both scrollbars should be shown"; + private static final String BACKGROUND = "#ddd"; + + @Override + public void init() { + super.init(); + + final Panel overflow = createScrollPanel(CONTENT1); + overflow.addStyleName("first-scrollbar"); + final Panel overflowX = createScrollPanel(CONTENT2); + overflowX.addStyleName("second-scrollbar"); + final Panel overflowY = createScrollPanel(CONTENT3); + overflowY.addStyleName("third-scrollbar"); + + Button runFix = new Button("Click to runWebkitOverflowAutoFix", + new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + overflow.getElement().getStyle() + .setOverflow(Style.Overflow.SCROLL); + WidgetUtil.runWebkitOverflowAutoFix(overflow + .getElement()); + + overflowX.getElement().getStyle() + .setOverflowX(Style.Overflow.HIDDEN); + WidgetUtil.runWebkitOverflowAutoFix(overflowX + .getElement()); + + overflowY.getElement().getStyle() + .setOverflowY(Style.Overflow.HIDDEN); + WidgetUtil.runWebkitOverflowAutoFix(overflowY + .getElement()); + } + }); + runFix.addStyleName("run-button-one"); + getWidget().add(runFix); + + Button runFix2 = new Button("Click to runWebkitOverflowAutoFix 2", + new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + overflow.getElement().getStyle() + .setOverflow(Style.Overflow.VISIBLE); + WidgetUtil.runWebkitOverflowAutoFix(overflow + .getElement()); + + overflowX.getElement().getStyle() + .setOverflowX(Style.Overflow.SCROLL); + WidgetUtil.runWebkitOverflowAutoFix(overflowX + .getElement()); + + overflowY.getElement().getStyle() + .setOverflowY(Style.Overflow.AUTO); + WidgetUtil.runWebkitOverflowAutoFix(overflowY + .getElement()); + } + }); + runFix2.addStyleName("run-button-two"); + getWidget().add(runFix2); + + addSpacer(10); + getWidget().add(overflow); + addSpacer(60); + getWidget().add(overflowX); + addSpacer(60); + getWidget().add(overflowY); + } + + private void addSpacer(double height) { + Element spacer = DOM.createDiv(); + spacer.getStyle().setHeight(height, Unit.PX); + spacer.getStyle().setWidth(10, Unit.PX); + getWidget().getElement().appendChild(spacer); + } + + private Panel createScrollPanel(String info) { + FlowPanel outer = new FlowPanel(); + outer.setPixelSize(300, 200); + getWidget().add(outer); + + HTML inner = new HTML(info); + inner.setPixelSize(350, 250); + inner.getElement().getStyle().setBackgroundColor(BACKGROUND); + // for some reason theme sets size to 0 + inner.getElement().getStyle().setFontSize(12, Style.Unit.PX); + outer.add(inner); + + return outer; + } + + @Override + public VVerticalLayout getWidget() { + return (VVerticalLayout) super.getWidget(); + } + + @Override + public VerticalLayoutState getState() { + return (VerticalLayoutState) super.getState(); + } + + @Override + public void updateCaption(ComponentConnector connector) { + } + + @Override + public void onConnectorHierarchyChange( + ConnectorHierarchyChangeEvent connectorHierarchyChangeEvent) { + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java index 265a93fb59..9e77438e36 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java @@ -676,7 +676,15 @@ public class GridBasicClientFeaturesWidget extends grid.setEnabled(!grid.isEnabled()); } }, "Component", "State"); + addMenuCommand("Reverse grid columns", new ScheduledCommand() { + @Override + public void execute() { + List<Column> columns = new ArrayList<Column>(grid.getColumns()); + Collections.reverse(columns); + grid.setColumnOrder(columns.toArray(new Column[columns.size()])); + } + }, "Component", "State"); addMenuCommand("Column Reordering", new ScheduledCommand() { @Override @@ -685,6 +693,34 @@ public class GridBasicClientFeaturesWidget extends .isColumnReorderingAllowed()); } }, "Component", "State"); + addMenuCommand("250px", new ScheduledCommand() { + + @Override + public void execute() { + grid.setWidth("250px"); + } + }, "Component", "State", "Width"); + addMenuCommand("500px", new ScheduledCommand() { + + @Override + public void execute() { + grid.setWidth("500px"); + } + }, "Component", "State", "Width"); + addMenuCommand("750px", new ScheduledCommand() { + + @Override + public void execute() { + grid.setWidth("750px"); + } + }, "Component", "State", "Width"); + addMenuCommand("1000px", new ScheduledCommand() { + + @Override + public void execute() { + grid.setWidth("1000px"); + } + }, "Component", "State", "Width"); } private void createColumnsMenu() { diff --git a/uitest/tb2/com/vaadin/tests/application/DeploymentConfigurationTest.html b/uitest/tb2/com/vaadin/tests/application/DeploymentConfigurationTest.html deleted file mode 100644 index 2bdb7c79a5..0000000000 --- a/uitest/tb2/com/vaadin/tests/application/DeploymentConfigurationTest.html +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://localhost:8070/" /> -<title>DeploymentConfigurationTest</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">DeploymentConfigurationTest</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.DeploymentConfigurationTest?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>exact:closeIdleSessions: true</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>exact:productionMode: false</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>exact:testParam: 42</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>exact:heartbeatInterval: 301</td> - <td></td> -</tr> -<tr> - <td>assertTextPresent</td> - <td>exact:resourceCacheTime: 3601</td> - <td></td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/tb2/com/vaadin/tests/application/DetachOldUIOnReload.html b/uitest/tb2/com/vaadin/tests/application/DetachOldUIOnReload.html deleted file mode 100644 index 33fc46f060..0000000000 --- a/uitest/tb2/com/vaadin/tests/application/DetachOldUIOnReload.html +++ /dev/null @@ -1,92 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.DetachOldUIOnReload?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> - <td>This is UI 0</td> -</tr> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.DetachOldUIOnReload</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::PID_SLog_row_0</td> - <td>1. UI 0 has been detached</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> - <td>This is UI 1</td> -</tr> -<tr> - <td>clickAndWait</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::PID_SLog_row_0</td> - <td>2. UI 1 has been detached</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> - <td>This is UI 2</td> -</tr> -<tr> - <td>open</td> - <td>/</td> - <td></td> -</tr> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.DetachOldUIOnReload</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::PID_SLog_row_0</td> - <td>3. UI 2 has been detached</td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationDetachOldUIOnReload::/VVerticalLayout[0]/Slot[2]/VVerticalLayout[0]/Slot[0]/VLabel[0]</td> - <td>This is UI 3</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/tb2/com/vaadin/tests/application/ErrorInUnloadEvent.html b/uitest/tb2/com/vaadin/tests/application/ErrorInUnloadEvent.html deleted file mode 100644 index ee200d7f5c..0000000000 --- a/uitest/tb2/com/vaadin/tests/application/ErrorInUnloadEvent.html +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://arturwin.office.itmill.com:8888/" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.ErrorInUnloadEvent?restartApplication</td> - <td></td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestsapplicationErrorInUnloadEvent::PID_Suser</td> - <td>66,14</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsapplicationErrorInUnloadEvent::PID_Suser</td> - <td>a</td> -</tr> -<tr> - <td>mouseClick</td> - <td>vaadin=runcomvaadintestsapplicationErrorInUnloadEvent::PID_Spwd</td> - <td>73,16</td> -</tr> -<tr> - <td>enterCharacter</td> - <td>vaadin=runcomvaadintestsapplicationErrorInUnloadEvent::PID_Spwd</td> - <td>d</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestsapplicationErrorInUnloadEvent::PID_Spwd</td> - <td>enter</td> -</tr> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.ErrorInUnloadEvent</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestsapplicationErrorInUnloadEvent::/VFormLayout[0]/VFormLayout$VFormLayoutTable[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VHorizontalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td> - <td>...Title...</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/tb2/com/vaadin/tests/application/VaadinSessionAttribute.html b/uitest/tb2/com/vaadin/tests/application/VaadinSessionAttribute.html deleted file mode 100644 index 150ab3ff3d..0000000000 --- a/uitest/tb2/com/vaadin/tests/application/VaadinSessionAttribute.html +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.application.VaadinSessionAttribute?restartApplication&attachMainFirst</td> - <td></td> -</tr> -<tr> - <td>click</td> - <td>vaadin=runcomvaadintestsapplicationVaadinSessionAttribute::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VButton[0]/domChild[0]/domChild[0]</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>//body/div[2]//h1</td> - <td>42 & 84</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/tb2/com/vaadin/tests/applicationservlet/MultipleServletConfiguration.html b/uitest/tb2/com/vaadin/tests/applicationservlet/MultipleServletConfiguration.html deleted file mode 100644 index 3b4452cc8d..0000000000 --- a/uitest/tb2/com/vaadin/tests/applicationservlet/MultipleServletConfiguration.html +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head profile="http://selenium-ide.openqa.org/profiles/test-case"> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="" /> -<title>New Test</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">New Test</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/embed1</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=embed1::/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VLabel[0]</td> - <td>A generic test for Buttons in different configurations</td> -</tr> -<tr> - <td>open</td> - <td>/embed2</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=embed2::/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VLabel[0]</td> - <td>Margins inside labels should not be allowed to collapse out of the label as it causes problems with layotus measuring the label.</td> -</tr> -<tr> - <td>open</td> - <td>/embed1</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=embed1::/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VLabel[0]</td> - <td>A generic test for Buttons in different configurations</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/tb2/com/vaadin/tests/applicationservlet/SystemMessagesTest.html b/uitest/tb2/com/vaadin/tests/applicationservlet/SystemMessagesTest.html deleted file mode 100644 index a764255b5b..0000000000 --- a/uitest/tb2/com/vaadin/tests/applicationservlet/SystemMessagesTest.html +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<link rel="selenium.base" href="http://localhost:8888/" />
-<title>New Test</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-<thead>
-<tr><td rowspan="1" colspan="3">New Test</td></tr>
-</thead><tbody>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.applicationservlet.SystemMessagesTest?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestsapplicationservletSystemMessagesTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestsapplicationservletSystemMessagesTest::Root/VNotification[0]/domChild[0]</td>
- <td>Internal error*MessagesInfo locale: fi_FI</td>
-</tr>
-<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.applicationservlet.SystemMessagesTest?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>select</td>
- <td>vaadin=runcomvaadintestsapplicationservletSystemMessagesTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VNativeSelect[0]/domChild[0]</td>
- <td>label=de_DE</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestsapplicationservletSystemMessagesTest::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestsapplicationservletSystemMessagesTest::Root/VNotification[0]/domChild[0]</td>
- <td>Internal error*MessagesInfo locale: de_DE</td>
-</tr>
-
-</tbody></table>
-</body>
-</html>
diff --git a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxBorder.html b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxBorder.html index 7e7bb7722d..bb83cbc097 100644 --- a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxBorder.html +++ b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxBorder.html @@ -34,11 +34,6 @@ <tr> <td>pressSpecialKey</td> <td>vaadin=runComboBoxBorder::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]#textbox</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runComboBoxBorder::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]#textbox</td> <td>enter</td> </tr> <tr> diff --git a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxCombinedWithEnterShortcut.html b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxCombinedWithEnterShortcut.html index 1689c7c1fc..c4d9fb0b3f 100644 --- a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxCombinedWithEnterShortcut.html +++ b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxCombinedWithEnterShortcut.html @@ -3,7 +3,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> -<link rel="selenium.base" href="http://arturwin.office.itmill.com:8888/" /> +<link rel="selenium.base" href="http://localhost:8888/" /> <title>New Test</title> </head> <body> @@ -34,11 +34,6 @@ <tr> <td>pressSpecialKey</td> <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxCombinedWithEnterShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxCombinedWithEnterShortcut::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VFilterSelect[0]/domChild[0]</td> <td>enter</td> </tr> <!--Enter in the popup should not send a shortcut event--> diff --git a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxLargeIcons.html b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxLargeIcons.html index fd2aceb7f2..ff6c82dfdb 100644 --- a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxLargeIcons.html +++ b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxLargeIcons.html @@ -138,16 +138,6 @@ <td>down</td> </tr> <tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboboxes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboboxes::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> <td>screenCapture</td> <td></td> <td>icons-64x64-page1-highlight-first</td> diff --git a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxNavigation.html b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxNavigation.html index 03de00a6f1..7722731f81 100644 --- a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxNavigation.html +++ b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxNavigation.html @@ -47,11 +47,6 @@ <td></td> </tr> <tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxNavigation::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]/domChild[0]</td> - <td>down</td> -</tr> -<tr> <td>waitForVaadin</td> <td></td> <td></td> diff --git a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxSQLContainerFilteredValueChange.html b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxSQLContainerFilteredValueChange.html index f3f44a5d90..c5bf3f7b99 100644 --- a/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxSQLContainerFilteredValueChange.html +++ b/uitest/tb2/com/vaadin/tests/components/combobox/ComboBoxSQLContainerFilteredValueChange.html @@ -24,11 +24,6 @@ <tr> <td>pressSpecialKey</td> <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSQLContainerFilteredValueChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]#textbox</td> - <td>down</td> -</tr> -<tr> - <td>pressSpecialKey</td> - <td>vaadin=runcomvaadintestscomponentscomboboxComboBoxSQLContainerFilteredValueChange::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VFilterSelect[0]#textbox</td> <td>enter</td> </tr> <tr> diff --git a/uitest/tb3test.xml b/uitest/tb3test.xml index ecacf43ee2..d3458a412b 100644 --- a/uitest/tb3test.xml +++ b/uitest/tb3test.xml @@ -9,6 +9,8 @@ <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" /> @@ -18,7 +20,8 @@ <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"> + <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> @@ -39,6 +42,8 @@ <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> diff --git a/widgets/build.xml b/widgets/build.xml index 5d012f4615..f8aba7fc81 100644 --- a/widgets/build.xml +++ b/widgets/build.xml @@ -97,16 +97,19 @@ <property name="jar.file" location="${result.dir}/lib/${module.name}-${vaadin.version}.jar" /> <antcall target="common.jar"> - <param name="src" value="${result.dir}/src" /> + <param name="src" value="${result.src}" /> <reference refid="jar.includes" torefid="extra.jar.includes" /> </antcall> </target> <target name="publish-local" depends="jar"> <antcall target="common.sources.jar"> + <param name="src" value="${result.src}" /> <reference torefid="extra.jar.includes" refid="jar.includes" /> </antcall> - <antcall target="common.javadoc.jar" /> + <antcall target="common.javadoc.jar"> + <param name="src" value="${result.src}" /> + </antcall> <antcall target="common.publish-local" /> </target> |