diff options
author | Jonatan Kronqvist <jonatan@vaadin.com> | 2014-02-10 09:39:50 +0200 |
---|---|---|
committer | Jonatan Kronqvist <jonatan@vaadin.com> | 2014-02-10 09:39:51 +0200 |
commit | ca911b69ee3bae0ca1f0ecc4002595ee81cb6b70 (patch) | |
tree | 742f083732699df2550dc71f533ff9a217841d5e | |
parent | ad5e882b4dda5458ff16ce9c2321407a1d255ec6 (diff) | |
parent | e5dee6a7417e4466ad35bd9150174f86204bca3e (diff) | |
download | vaadin-framework-ca911b69ee3bae0ca1f0ecc4002595ee81cb6b70.tar.gz vaadin-framework-ca911b69ee3bae0ca1f0ecc4002595ee81cb6b70.zip |
Merge changes from origin/7.1
c551507 Selected option is updated when item caption changes in Select (#9250)
3595685 Converted TestUIWidgetset test to TB3 and fixed wrong text in assertion.
89d860c Convinience methods for getting mouse and keyboard in test.
d00397f Converted TB2 test to TB3 and fixed text assertion.
857de0f Renamed test according to conventions and fixed assertion text.
b9a6a48 Update textbox when Select item caption changes (#9250)
1687889 Retain focus while changing DOM in OrderedLayout (#12967)
f93c870 Remove unselected rows from selection on client side (#13008)
1d1ccf4 Fix Firefox and Vaadin 7 scroll distance (#11353)
62ac53a Ensure widgetset compile messages go to stdout (#7516)
171d02a Remove references to read/write through modes (#13184)
3f09c10 Better-looking CSS for Vaadin API Javadocs (#13219)
f0a4ea9 Do not throw NPE for equals(null) (#8910)
3897025 Add deprecated expand ratio methods to FormLayout (#12876)
b89dba9 Exclude a possible bin directory when building (#13258)
69983d0 Re-adjusted the rendering order of TabSheet tabs to prevent an NPE in isClipped (#12343)
e5dee6a Use Calendar as sender for action handlers (#13191)
Change-Id: I581ec7517aaa19a2e46b48e31cdefdd3db2c05c5
34 files changed, 1167 insertions, 182 deletions
diff --git a/WebContent/VAADIN/themes/base/common/common.scss b/WebContent/VAADIN/themes/base/common/common.scss index 07e244a76f..5cae1b26ce 100644 --- a/WebContent/VAADIN/themes/base/common/common.scss +++ b/WebContent/VAADIN/themes/base/common/common.scss @@ -227,6 +227,10 @@ input::-ms-clear { font-size: 0; line-height: normal; } +/* Set font-size in order to make Firefox scrolling better #11353 */ +.v-ff & .v-scrollable { + font-size: $font-size; +} .v-ios.v-webkit & .v-scrollable { -webkit-overflow-scrolling: touch; } diff --git a/all/build.xml b/all/build.xml index 1b48721ecd..36a9499dea 100644 --- a/all/build.xml +++ b/all/build.xml @@ -43,7 +43,8 @@ <property name="javadoc.dir" location="${result.dir}/javadoc" /> <property name="title" value="Vaadin ${vaadin.version} API" /> - <javadoc maxmemory="1024m" destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="${title}" encoding="utf-8"> + <javadoc maxmemory="1024m" destdir="${javadoc.dir}" author="true" version="true" use="true" windowtitle="${title}" encoding="utf-8" + stylesheetfile="javadoc.css"> <packageset dir="${javadoc.temp.dir}"> <!-- TODO Javadoc throws ClassCastException if this is included (#9660) --> diff --git a/all/javadoc.css b/all/javadoc.css new file mode 100644 index 0000000000..ffa7288ad4 --- /dev/null +++ b/all/javadoc.css @@ -0,0 +1,236 @@ +@charset "UTF-8"; + +/* + * stylesheet for Vaadin Javadoc when compiled with Java 6 + */ +body { + background-color: rgb(244, 244, 240); + color: rgb(70, 68, 64); + font-size: 16px; + font-family: Helvetica, Arial, sans-serif; + font-weight: lighter; + line-height: 18px; + margin: 10px 14px; +} + +body[onload] { + background-color: rgb(255, 255, 255); + margin: 8px 23px; +} + +a:link,a:visited { + color: rgb(0, 180, 240); + text-decoration: none; +} + +b { + font-weight: bolder; +} + +code,pre { + font-family: Courier, monospace; +} + +dt { + font-size: 12px; + color: rgb(120, 119, 109); + text-transform: uppercase; +} + +dd>dl>dt { + font-size: 13px; + text-transform: none; +} + +h2+dl>dt { + text-transform: none; +} + +dt>pre,pre>dt { + text-transform: initial; +} + +dd { + font-size: 14px; + margin-left: 2.5em; +} + +dd:first-child { + font-size: 13px; +} + +dd>dl>dd { + font-size: 12px; +} + +h1 { + font-size: 32px +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 16px; +} + +h1,h2,h3 { + line-height: 30px; +} + +hr { + border: 1px solid rgb(233, 233, 225); +} + +pre,h2+ul { + font-size: 12px; +} + +table { + border: none; + border-collapse: collapse; +} + +td { + padding: 0; +} + +th { + padding: 0 1ch; +} + +.TableHeadingColor,.TableSubHeadingColor { + line-height: 30px; +} + +.TableHeadingColor>th,.TableHeadingColor>th>font>b,.TableSubHeadingColor>th,.TableSubHeadingColor>th>b + { + font-weight: inherit; +} + +.TableHeadingColor>th>font { + font-size: 18px; +} + +.TableSubHeadingColor { + font-size: 14px; +} + +.TableHeadingColor,.TableSubHeadingColor { + background: rgb(233, 233, 225); +} + +.TableRowColor { + background: #FFFFFF; +} + +.TableRowColor:nth-child(odd) { + background-color: rgb(244, 244, 240); +} + +.TableRowColor>td { + font-size: 12px; + border: none; + padding: 1ex 1ch +} + +.TableRowColor>td>font { + font-size: 11px; +} + +.TableHeadingColor,.TableRowColor,.TableSubHeadingColor>th { + border: none; + border-color: transparent; +} + +table[border="1"] { + border: 2px solid rgb(233, 233, 225); +} + +.FrameTitleFont { + font-size: 18px; + font-family: Helvetica, Arial, sans-serif; + font-weight: bolder; + line-height: 30px; +} + +.FrameHeadingFont { + font-size: 12px; + font-family: Helvetica, Arial, sans-serif; + font-weight: bold; + color: rgb(120, 119, 109); + text-transform: uppercase; + display: inline-block; + margin-bottom: 4px; +} + +td>.FrameHeadingFont { + margin-top: 12px; +} + +.FrameItemFont { + font-size: 90%; + font-family: Helvetica, Arial, sans-serif; +} + +.NavBarCell1 { + background-color: rgb(245, 245, 241); + border: 2px solid rgb(245, 245, 241); +} + +.NavBarCell1+td[rowspan="3"] { + display: none; +} + +.NavBarCell1,.NavBarCell1Rev { + font-size: 0; +} + +.NavBarCell1>*,.NavBarCell1Rev>* { + font-size: 14px; +} + +.NavBarCell1 .NavBarCell1,.NavBarCell1 .NavBarCell1Rev { + padding: 3px 8px; + line-height: 1; + vertical-align: baseline; +} + +.NavBarCell1Rev { + background-color: rgb(0, 180, 240); + border-radius: 3px; +} + +.NavBarFont1 { + font-family: Helvetica, Arial, sans-serif; + color: rgb(70, 68, 64); +} + +.NavBarFont1Rev { + font-family: Helvetica, Arial, sans-serif; + color: rgb(255, 255, 255); +} + +.NavBarCell2 { + font-family: Helvetica, Arial, sans-serif; + background-color: #FFFFFF; + padding-top: 6px; +} + +.NavBarCell2:first-child { + color: transparent; +} + +.NavBarCell2>font,.NavBarCell3>font { + font-size: 11px; +} + +.NavBarCell2>font>a>b { + font-weight: normal; +} + +.NavBarCell3 { + font-family: Helvetica, Arial, sans-serif; + background-color: #FFFFFF; +}
\ No newline at end of file @@ -19,6 +19,7 @@ <fileset dir="." includes="**/build.xml"> <exclude name="build.xml" /> <exclude name="build/**" /> + <exclude name="bin/**" /> <exclude name="buildhelpers/**" /> </fileset> </ivy:buildlist> diff --git a/client/src/com/vaadin/client/ui/VScrollTable.java b/client/src/com/vaadin/client/ui/VScrollTable.java index 3a7e15626a..10dbc71901 100644 --- a/client/src/com/vaadin/client/ui/VScrollTable.java +++ b/client/src/com/vaadin/client/ui/VScrollTable.java @@ -1060,6 +1060,8 @@ public class VScrollTable extends FlowPanel implements HasWidgets, if (uidl.hasVariable("selected")) { final Set<String> selectedKeys = uidl .getStringArrayVariableAsSet("selected"); + removeUnselectedRowKeys(selectedKeys); + if (scrollBody != null) { Iterator<Widget> iterator = scrollBody.iterator(); while (iterator.hasNext()) { @@ -1102,6 +1104,16 @@ public class VScrollTable extends FlowPanel implements HasWidgets, return keyboardSelectionOverRowFetchInProgress; } + private void removeUnselectedRowKeys(final Set<String> selectedKeys) { + List<String> unselectedKeys = new ArrayList<String>(0); + for (String key : selectedRowKeys) { + if (!selectedKeys.contains(key)) { + unselectedKeys.add(key); + } + } + selectedRowKeys.removeAll(unselectedKeys); + } + /** For internal use only. May be removed or replaced in the future. */ public void updateSortingProperties(UIDL uidl) { oldSortColumn = sortColumn; diff --git a/client/src/com/vaadin/client/ui/VTabsheet.java b/client/src/com/vaadin/client/ui/VTabsheet.java index 34904405c7..82eb9e7694 100644 --- a/client/src/com/vaadin/client/ui/VTabsheet.java +++ b/client/src/com/vaadin/client/ui/VTabsheet.java @@ -948,8 +948,8 @@ public class VTabsheet extends VTabsheetBase implements Focusable, tab = tb.addTab(); } if (selected) { - renderContent(tabUidl.getChildUIDL(0)); tb.selectTab(index); + renderContent(tabUidl.getChildUIDL(0)); } tab.updateFromUIDL(tabUidl); tab.setEnabledOnServer((!disabledTabKeys.contains(tabKeys.get(index)))); diff --git a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java index f91ff9e2b9..8dec26cf90 100644 --- a/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java +++ b/client/src/com/vaadin/client/ui/combobox/ComboBoxConnector.java @@ -37,6 +37,10 @@ import com.vaadin.ui.ComboBox; public class ComboBoxConnector extends AbstractFieldConnector implements Paintable, SimpleManagedLayout { + // oldSuggestionTextMatchTheOldSelection is used to detect when it's safe to + // update textbox text by a changed item caption. + private boolean oldSuggestionTextMatchTheOldSelection; + /* * (non-Javadoc) * @@ -117,7 +121,10 @@ public class ComboBoxConnector extends AbstractFieldConnector implements boolean suggestionsChanged = !getWidget().initDone || !newSuggestions.equals(getWidget().currentSuggestions); + oldSuggestionTextMatchTheOldSelection = false; + if (suggestionsChanged) { + oldSuggestionTextMatchTheOldSelection = isWidgetsCurrentSelectionTextInTextBox(); getWidget().currentSuggestions.clear(); if (!getWidget().waitingForFilteringResponse) { @@ -212,29 +219,38 @@ public class ComboBoxConnector extends AbstractFieldConnector implements // some item selected for (FilterSelectSuggestion suggestion : getWidget().currentSuggestions) { String suggestionKey = suggestion.getOptionKey(); - if (suggestionKey.equals(selectedKey)) { - if (!getWidget().waitingForFilteringResponse - || getWidget().popupOpenerClicked) { - if (!suggestionKey.equals(getWidget().selectedOptionKey) - || suggestion.getReplacementString().equals( - getWidget().tb.getText())) { - // Update text field if we've got a new - // selection - // Also update if we've got the same text to - // retain old text selection behavior - getWidget().setPromptingOff( - suggestion.getReplacementString()); - getWidget().selectedOptionKey = suggestionKey; - } + if (!suggestionKey.equals(selectedKey)) { + continue; + } + if (!getWidget().waitingForFilteringResponse + || getWidget().popupOpenerClicked) { + if (!suggestionKey.equals(getWidget().selectedOptionKey) + || suggestion.getReplacementString().equals( + getWidget().tb.getText()) + || oldSuggestionTextMatchTheOldSelection) { + // Update text field if we've got a new + // selection + // Also update if we've got the same text to + // retain old text selection behavior + // OR if selected item caption is changed. + getWidget().setPromptingOff( + suggestion.getReplacementString()); + getWidget().selectedOptionKey = suggestionKey; } - getWidget().currentSuggestion = suggestion; - getWidget().setSelectedItemIcon(suggestion.getIconUri()); - // only a single item can be selected - break; } + getWidget().currentSuggestion = suggestion; + getWidget().setSelectedItemIcon(suggestion.getIconUri()); + // only a single item can be selected + break; } } + private boolean isWidgetsCurrentSelectionTextInTextBox() { + return getWidget().currentSuggestion != null + && getWidget().currentSuggestion.getReplacementString().equals( + getWidget().tb.getText()); + } + private void resetSelection() { if (!getWidget().waitingForFilteringResponse || getWidget().popupOpenerClicked) { diff --git a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java index 49b3661431..37a97f3399 100644 --- a/client/src/com/vaadin/client/ui/orderedlayout/Slot.java +++ b/client/src/com/vaadin/client/ui/orderedlayout/Slot.java @@ -19,9 +19,11 @@ package com.vaadin.client.ui.orderedlayout; import java.util.List; import com.google.gwt.aria.client.Roles; +import com.google.gwt.dom.client.Document; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.UIObject; import com.google.gwt.user.client.ui.Widget; @@ -456,6 +458,9 @@ public final class Slot extends SimplePanel { // Caption wrappers Widget widget = getWidget(); + final Element focusedElement = Util.getFocusedElement(); + // By default focus will not be lost + boolean focusLost = false; if (captionText != null || iconUrl != null || error != null || required) { if (caption == null) { caption = DOM.createDiv(); @@ -466,6 +471,10 @@ public final class Slot extends SimplePanel { orphan(widget); captionWrap.appendChild(widget.getElement()); adopt(widget); + + // Made changes to DOM. Focus can be lost if it was in the + // widget. + focusLost = widget.getElement().isOrHasChild(focusedElement); } } else if (caption != null) { orphan(widget); @@ -474,6 +483,9 @@ public final class Slot extends SimplePanel { captionWrap.removeFromParent(); caption = null; captionWrap = null; + + // Made changes to DOM. Focus can be lost if it was in the widget. + focusLost = widget.getElement().isOrHasChild(focusedElement); } // Caption text @@ -560,6 +572,45 @@ public final class Slot extends SimplePanel { setCaptionPosition(CaptionPosition.RIGHT); } } + + if (focusLost) { + // Find out what element is currently focused. + Element currentFocus = Util.getFocusedElement(); + if (currentFocus != null + && currentFocus.equals(Document.get().getBody())) { + // Focus has moved to BodyElement and should be moved back to + // original location. This happened because of adding or + // removing the captionWrap + focusedElement.focus(); + } else if (currentFocus != focusedElement) { + // Focus is either moved somewhere else on purpose or IE has + // lost it. Investigate further. + Timer focusTimer = new Timer() { + + @Override + public void run() { + if (Util.getFocusedElement() == null) { + // This should never become an infinite loop and + // even if it does it will be stopped once something + // is done with the browser. + schedule(25); + } else if (Util.getFocusedElement().equals( + Document.get().getBody())) { + // Focus found it's way to BodyElement. Now it can + // be restored + focusedElement.focus(); + } + } + }; + if (BrowserInfo.get().isIE8()) { + // IE8 can't fix the focus immediately. It will fail. + focusTimer.schedule(25); + } else { + // Newer IE versions can handle things immediately. + focusTimer.run(); + } + } + } } /** diff --git a/server/src/com/vaadin/data/Buffered.java b/server/src/com/vaadin/data/Buffered.java index 0d6722f71f..c4c79ae13f 100644 --- a/server/src/com/vaadin/data/Buffered.java +++ b/server/src/com/vaadin/data/Buffered.java @@ -23,29 +23,20 @@ import com.vaadin.data.Validator.InvalidValueException; /** * <p> * Defines the interface to commit and discard changes to an object, supporting - * read-through and write-through modes. - * </p> + * buffering. * * <p> - * <i>Read-through mode</i> means that the value read from the buffered object - * is constantly up to date with the data source. <i>Write-through</i> mode - * means that all changes to the object are immediately updated to the data - * source. - * </p> + * In <i>buffered</i> mode the initial value is read from the data source and + * then buffered. Any subsequential writes or reads will be done on the buffered + * value. Calling {@link #commit()} will write the buffered value to the data + * source while calling {@link #discard()} while discard the buffered value and + * re-read the value from the data source. * * <p> - * Since these modes are independent, their combinations may result in some - * behaviour that may sound surprising. - * </p> - * - * <p> - * For example, if a <code>Buffered</code> object is in read-through mode but - * not in write-through mode, the result is an object whose value is updated - * directly from the data source only if it's not locally modified. If the value - * is locally modified, retrieving the value from the object would result in a - * value that is different than the one stored in the data source, even though - * the object is in read-through mode. - * </p> + * In <i>non-buffered</i> mode the value is always read directly from the data + * source. Any write is done directly to the data source with no buffering in + * between. Reads are also done directly from the data source. Calling + * {@link #commit()} or {@link #discard()} in this mode is efficiently a no-op. * * @author Vaadin Ltd. * @since 3.0 @@ -77,25 +68,15 @@ public interface Buffered extends Serializable { public void discard() throws SourceException; /** - * Sets the object's buffered mode to the specified status. + * Sets the buffered mode to the specified status. * <p> - * When the object is in buffered mode, an internal buffer will be used to - * store changes until {@link #commit()} is called. Calling - * {@link #discard()} will revert the internal buffer to the value of the - * data source. - * </p> + * When in buffered mode, an internal buffer will be used to store changes + * until {@link #commit()} is called. Calling {@link #discard()} will revert + * the internal buffer to the value of the data source. * <p> - * This is an easier way to use {@link #setReadThrough(boolean)} and - * {@link #setWriteThrough(boolean)} and not as error prone. Changing - * buffered mode will change both the read through and write through state - * of the object. - * </p> - * <p> - * Mixing calls to {@link #setBuffered(boolean)}/{@link #isBuffered()} and - * {@link #setReadThrough(boolean)}/{@link #isReadThrough()} or - * {@link #setWriteThrough(boolean)}/{@link #isWriteThrough()} is generally - * a bad idea. - * </p> + * When in non-buffered mode both read and write operations will be done + * directly on the data source. In this mode the {@link #commit()} and + * {@link #discard()} methods serve no purpose. * * @param buffered * true if buffered mode should be turned on, false otherwise @@ -104,10 +85,7 @@ public interface Buffered extends Serializable { public void setBuffered(boolean buffered); /** - * Checks the buffered mode of this Object. - * <p> - * This method only returns true if both read and write buffering is used. - * </p> + * Checks the buffered mode * * @return true if buffered mode is on, false otherwise * @since 7.0 diff --git a/server/src/com/vaadin/data/util/filter/Between.java b/server/src/com/vaadin/data/util/filter/Between.java index 8209f7b0a2..a76821981a 100644 --- a/server/src/com/vaadin/data/util/filter/Between.java +++ b/server/src/com/vaadin/data/util/filter/Between.java @@ -67,6 +67,10 @@ public class Between implements Filter { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + // Only objects of the same class can be equal if (!getClass().equals(obj.getClass())) { return false; diff --git a/server/src/com/vaadin/data/util/filter/Compare.java b/server/src/com/vaadin/data/util/filter/Compare.java index f9f19c6602..ac167673bd 100644 --- a/server/src/com/vaadin/data/util/filter/Compare.java +++ b/server/src/com/vaadin/data/util/filter/Compare.java @@ -307,6 +307,9 @@ public abstract class Compare implements Filter { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } // Only objects of the same class can be equal if (!getClass().equals(obj.getClass())) { diff --git a/server/src/com/vaadin/data/util/filter/IsNull.java b/server/src/com/vaadin/data/util/filter/IsNull.java index 5c5bdfc0b1..6907a016a1 100644 --- a/server/src/com/vaadin/data/util/filter/IsNull.java +++ b/server/src/com/vaadin/data/util/filter/IsNull.java @@ -62,6 +62,10 @@ public final class IsNull implements Filter { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + // Only objects of the same class can be equal if (!getClass().equals(obj.getClass())) { return false; diff --git a/server/src/com/vaadin/data/util/filter/Like.java b/server/src/com/vaadin/data/util/filter/Like.java index 4c15564105..dc2e18363a 100644 --- a/server/src/com/vaadin/data/util/filter/Like.java +++ b/server/src/com/vaadin/data/util/filter/Like.java @@ -84,6 +84,10 @@ public class Like implements Filter { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + // Only objects of the same class can be equal if (!getClass().equals(obj.getClass())) { return false; diff --git a/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java b/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java index bc58999445..a214e69846 100644 --- a/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java +++ b/server/src/com/vaadin/data/util/filter/SimpleStringFilter.java @@ -82,6 +82,9 @@ public final class SimpleStringFilter implements Filter { @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } // Only ones of the objects of the same class can be equal if (!(obj instanceof SimpleStringFilter)) { diff --git a/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java b/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java index cc04e50b3c..3ad76794de 100644 --- a/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java +++ b/server/src/com/vaadin/server/widgetsetutils/ClassPathExplorer.java @@ -32,8 +32,6 @@ import java.util.Set; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Utility class to collect widgetset related information from classpath. @@ -111,6 +109,15 @@ public class ClassPathExplorer { */ private static Map<String, URL> classpathLocations = getClasspathLocations(rawClasspathEntries); + private static boolean debug = false; + + static { + String debugProperty = System.getProperty("debug"); + if (debugProperty != null && !debugProperty.equals("")) { + debug = true; + } + } + /** * No instantiation from outside, callable methods are static. */ @@ -163,9 +170,8 @@ public class ClassPathExplorer { sb.append("\n"); } - final Logger logger = getLogger(); - logger.info(sb.toString()); - logger.info("Search took " + (end - start) + "ms"); + log(sb.toString()); + log("Search took " + (end - start) + "ms"); return new LocationInfo(widgetsets, themes); } @@ -226,8 +232,7 @@ public class ClassPathExplorer { } catch (MalformedURLException e) { // should never happen as based on an existing URL, // only changing end of file name/path part - getLogger().log(Level.SEVERE, - "Error locating the widgetset " + classname, e); + error("Error locating the widgetset " + classname, e); } } } @@ -276,7 +281,7 @@ public class ClassPathExplorer { } } } catch (IOException e) { - getLogger().log(Level.WARNING, "Error parsing jar file", e); + error("Error parsing jar file", e); } } @@ -304,7 +309,7 @@ public class ClassPathExplorer { classpath = classpath.substring(0, classpath.length() - 1); } - getLogger().log(Level.FINE, "Classpath: {0}", classpath); + debug("Classpath: " + classpath); String[] split = classpath.split(pathSep); for (int i = 0; i < split.length; i++) { @@ -338,9 +343,8 @@ public class ClassPathExplorer { include(null, file, locations); } long end = System.currentTimeMillis(); - Logger logger = getLogger(); - if (logger.isLoggable(Level.FINE)) { - logger.fine("getClassPathLocations took " + (end - start) + "ms"); + if (debug) { + debug("getClassPathLocations took " + (end - start) + "ms"); } return locations; } @@ -379,7 +383,8 @@ public class ClassPathExplorer { url = new URL("jar:" + url.toExternalForm() + "!/"); JarURLConnection conn = (JarURLConnection) url .openConnection(); - getLogger().fine(url.toString()); + debug(url.toString()); + JarFile jarFile = conn.getJarFile(); Manifest manifest = jarFile.getManifest(); if (manifest != null) { @@ -393,11 +398,13 @@ public class ClassPathExplorer { } } } catch (MalformedURLException e) { - getLogger().log(Level.FINEST, "Failed to inspect JAR file", - e); + if (debug) { + error("Failed to inspect JAR file", e); + } } catch (IOException e) { - getLogger().log(Level.FINEST, "Failed to inspect JAR file", - e); + if (debug) { + error("Failed to inspect JAR file", e); + } } return false; @@ -489,14 +496,12 @@ public class ClassPathExplorer { */ public static URL getDefaultSourceDirectory() { - final Logger logger = getLogger(); - - if (logger.isLoggable(Level.FINE)) { - logger.fine("classpathLocations values:"); + if (debug) { + debug("classpathLocations values:"); ArrayList<String> locations = new ArrayList<String>( classpathLocations.keySet()); for (String location : locations) { - logger.fine(String.valueOf(classpathLocations.get(location))); + debug(String.valueOf(classpathLocations.get(location))); } } @@ -510,11 +515,15 @@ public class ClassPathExplorer { try { return new URL("file://" + directory.getCanonicalPath()); } catch (MalformedURLException e) { - logger.log(Level.FINEST, "Ignoring exception", e); // ignore: continue to the next classpath entry + if (debug) { + e.printStackTrace(); + } } catch (IOException e) { - logger.log(Level.FINEST, "Ignoring exception", e); // ignore: continue to the next classpath entry + if (debug) { + e.printStackTrace(); + } } } } @@ -525,14 +534,24 @@ public class ClassPathExplorer { * Test method for helper tool */ public static void main(String[] args) { - getLogger().info( - "Searching for available widgetsets and stylesheets..."); + log("Searching for available widgetsets and stylesheets..."); ClassPathExplorer.getAvailableWidgetSetsAndStylesheets(); } - private static final Logger getLogger() { - return Logger.getLogger(ClassPathExplorer.class.getName()); + private static void log(String message) { + System.out.println(message); + } + + private static void error(String message, Exception e) { + System.err.println(message); + e.printStackTrace(); + } + + private static void debug(String message) { + if (debug) { + System.out.println(message); + } } } diff --git a/server/src/com/vaadin/ui/Calendar.java b/server/src/com/vaadin/ui/Calendar.java index 9ccc8ea2d9..b0999451c3 100644 --- a/server/src/com/vaadin/ui/Calendar.java +++ b/server/src/com/vaadin/ui/Calendar.java @@ -1824,7 +1824,7 @@ public class Calendar extends AbstractComponent implements try { Date start = formatter.parse(startDate); for (Action.Handler ah : actionHandlers) { - ah.handleAction(action, this, start); + ah.handleAction(action, Calendar.this, start); } } catch (ParseException e) { @@ -1842,7 +1842,7 @@ public class Calendar extends AbstractComponent implements DateConstants.ACTION_DATE_FORMAT_PATTERN); formatter.setTimeZone(getTimeZone()); for (Action.Handler ah : actionHandlers) { - ah.handleAction(action, this, events.get(eventIndex)); + ah.handleAction(action, Calendar.this, events.get(eventIndex)); } } } diff --git a/server/src/com/vaadin/ui/FormLayout.java b/server/src/com/vaadin/ui/FormLayout.java index 9d5e637068..9dc0b24cad 100644 --- a/server/src/com/vaadin/ui/FormLayout.java +++ b/server/src/com/vaadin/ui/FormLayout.java @@ -52,4 +52,23 @@ public class FormLayout extends AbstractOrderedLayout { addComponents(children); } + /** + * @deprecated This method currently has no effect as expand ratios are not + * implemented in FormLayout + */ + @Override + @Deprecated + public void setExpandRatio(Component component, float ratio) { + super.setExpandRatio(component, ratio); + } + + /** + * @deprecated This method currently has no effect as expand ratios are not + * implemented in FormLayout + */ + @Override + @Deprecated + public float getExpandRatio(Component component) { + return super.getExpandRatio(component); + } } diff --git a/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java new file mode 100644 index 0000000000..c8faa71e66 --- /dev/null +++ b/server/tests/src/com/vaadin/data/util/sqlcontainer/filters/CompareTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.data.util.sqlcontainer.filters; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.data.util.filter.Compare; + +public class CompareTest { + + @Test + public void testEquals() { + Compare c1 = new Compare.Equal("prop1", "val1"); + Compare c2 = new Compare.Equal("prop1", "val1"); + Assert.assertTrue(c1.equals(c2)); + } + + @Test + public void testDifferentTypeEquals() { + Compare c1 = new Compare.Equal("prop1", "val1"); + Compare c2 = new Compare.Greater("prop1", "val1"); + Assert.assertFalse(c1.equals(c2)); + } + + @Test + public void testEqualsNull() { + Compare c1 = new Compare.Equal("prop1", "val1"); + Assert.assertFalse(c1.equals(null)); + } +} diff --git a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.java b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java index c2222c4608..9d1b052182 100644 --- a/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClass.java +++ b/uitest/src/com/vaadin/tests/applicationservlet/NoApplicationClassTest.java @@ -25,7 +25,7 @@ import org.openqa.selenium.remote.DesiredCapabilities; import com.vaadin.tests.tb3.MultiBrowserTest; -public class NoApplicationClass extends MultiBrowserTest { +public class NoApplicationClassTest extends MultiBrowserTest { @Test public void testInvalidApplicationClass() { @@ -33,7 +33,7 @@ public class NoApplicationClass extends MultiBrowserTest { String exceptionMessage = getDriver().findElement(By.xpath("//pre[2]")) .getText(); Assert.assertTrue(exceptionMessage - .contains("ServletException: ClassThatIsNotPresent")); + .contains("ServletException: java.lang.ClassNotFoundException: ClassThatIsNotPresent")); } @Override diff --git a/uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java b/uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java new file mode 100644 index 0000000000..b6358b6c56 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/UnknownComponentConnector.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.components; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.AbstractComponent; + +public class UnknownComponentConnector extends AbstractTestUI { + + public static class ComponentWithoutConnector extends AbstractComponent { + + } + + @Override + protected void setup(VaadinRequest request) { + ComponentWithoutConnector component = new ComponentWithoutConnector(); + component.setId("no-connector-component"); + addComponent(component); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html b/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html deleted file mode 100644 index 20f0e8e71e..0000000000 --- a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.html +++ /dev/null @@ -1,27 +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.components.UnknownComponentConnectorTest?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsUnknownComponentConnectorTest::/VVerticalLayout[0]/VVerticalLayout[0]/VUnknownComponent[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>Widgetset does not contain implementation for com.vaadin.tests.components.UnknownComponentConnectorTest.ComponentWithoutConnector. Check its component connector's @Connect mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions.</td> -</tr> - -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java b/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java index ff113d631e..49a3c29e2d 100644 --- a/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java +++ b/uitest/src/com/vaadin/tests/components/UnknownComponentConnectorTest.java @@ -13,33 +13,29 @@ * License for the specific language governing permissions and limitations under * the License. */ - package com.vaadin.tests.components; -import com.vaadin.server.VaadinRequest; -import com.vaadin.ui.AbstractComponent; - -public class UnknownComponentConnectorTest extends AbstractTestUI { +import static org.junit.Assert.assertTrue; - public static class ComponentWithoutConnector extends AbstractComponent { +import org.junit.Test; +import org.openqa.selenium.WebElement; - } - - @Override - protected void setup(VaadinRequest request) { - addComponent(new ComponentWithoutConnector()); - } +import com.vaadin.tests.tb3.MultiBrowserTest; - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; +/** + * Tests that a user is notified about a missing component from the widgetset + */ +public class UnknownComponentConnectorTest extends MultiBrowserTest { + + @Test + public void testConnectorNotFoundInWidgetset() throws Exception { + openTestURL(); + WebElement component = vaadinElementById("no-connector-component"); + assertTrue(component + .getText() + .startsWith( + "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain " + + "implementation for com.vaadin.tests.components.UnknownComponentConnector." + + "ComponentWithoutConnector.")); } - } diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java new file mode 100644 index 0000000000..5e81750e58 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSource.java @@ -0,0 +1,114 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.calendar; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Calendar; +import com.vaadin.ui.Calendar.TimeFormat; +import com.vaadin.ui.Label; +import com.vaadin.ui.components.calendar.CalendarComponentEvents.EventResizeHandler; +import com.vaadin.ui.components.calendar.event.BasicEvent; +import com.vaadin.ui.components.calendar.event.CalendarEvent; +import com.vaadin.ui.components.calendar.event.CalendarEventProvider; + +public class CalendarActionEventSource extends AbstractTestUI { + + private Calendar calendar; + + @Override + protected void setup(VaadinRequest request) { + calendar = new Calendar(new CalendarEventProvider() { + + @Override + public List<com.vaadin.ui.components.calendar.event.CalendarEvent> getEvents( + Date startDate, Date endDate) { + + List<CalendarEvent> events = new ArrayList<CalendarEvent>(); + + CalendarEvent event = null; + try { + event = new BasicEvent("NAME", "TOOLTIP", + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .parse("2013-01-01 07:00"), + new SimpleDateFormat("yyyy-MM-dd hh:mm") + .parse("2013-01-01 11:00")); + } catch (ParseException e) { + // Nothing to do + } + events.add(event); + + return events; + } + + }); + try { + calendar.setStartDate(new SimpleDateFormat("yyyy-MM-dd") + .parse("2013-01-01")); + calendar.setEndDate(new SimpleDateFormat("yyyy-MM-dd") + .parse("2013-01-31")); + } catch (ParseException e) { + // Nothing to do + } + calendar.setImmediate(true); + calendar.setFirstVisibleHourOfDay(6); + calendar.setLastVisibleHourOfDay(22); + calendar.setTimeFormat(TimeFormat.Format24H); + calendar.setHandler((EventResizeHandler) null); + + setEnabled(true); + calendar.addActionHandler(new Handler() { + @Override + public void handleAction(Action action, Object sender, Object target) { + Label label1 = new Label(calendar.toString()); + label1.setId("calendarlabel"); + addComponent(label1); + + Label label2 = new Label(sender.toString()); + label2.setId("senderlabel"); + addComponent(label2); + } + + @Override + public Action[] getActions(Object target, Object sender) { + return new Action[] { new Action("ACTION") }; + } + }); + addComponent(calendar); + calendar.setSizeFull(); + setSizeFull(); + + } + + @Override + protected String getTestDescription() { + return "Calendar action event source should be the calendar itself"; + } + + @Override + protected Integer getTicketNumber() { + return 13191; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java new file mode 100644 index 0000000000..6fbe77040f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/calendar/CalendarActionEventSourceTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.calendar; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.tb3.PrivateTB3Configuration; + +/** + * Test that calendar action event source is the calendar, not a private nested + * class in it. + * + * The related code is not browser dependent so only running on a single + * browser. + * + * @author Vaadin Ltd + */ +public class CalendarActionEventSourceTest extends PrivateTB3Configuration { + @Test + public void testActionEventSourceIsCalendarForEmptyCell() throws Exception { + openTestURL(); + + // perform action on empty cell + WebElement element = getDriver().findElement( + By.className("v-calendar-spacer")); + performAction(element); + + checkEventSourceIsCalendar(); + } + + @Test + public void testActionEventSourceIsCalendarForEvent() throws Exception { + openTestURL(); + + // perform action on calendar event + WebElement element = getDriver().findElement( + By.className("v-calendar-event")); + performAction(element); + + checkEventSourceIsCalendar(); + } + + private void performAction(WebElement element) { + // right click + new Actions(getDriver()).contextClick(element).perform(); + WebElement menuItem = getDriver().findElement( + By.className("gwt-MenuItem")); + menuItem.click(); + } + + private void checkEventSourceIsCalendar() { + String calendarObject = getDriver().findElement(By.id("calendarlabel")) + .getText(); + String actionSourceObject = getDriver().findElement( + By.id("senderlabel")).getText(); + Assert.assertEquals( + "Calendar action event source must be the calendar itself", + calendarObject, actionSourceObject); + } + + @Override + protected Class<?> getUIClass() { + return CalendarActionEventSource.class; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java new file mode 100644 index 0000000000..1e7d817094 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChanges.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.orderedlayout; + +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.Button; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +public class VerticalLayoutFocusWithDOMChanges extends AbstractTestUI implements + ValueChangeListener { + + Button dummyButton = new Button("Just a button"); + TextField listenedTextField = new TextField(); + TextField changingTextField = new TextField(); + + @Override + protected void setup(VaadinRequest request) { + VerticalLayout content = new VerticalLayout(); + setSizeFull(); + listenedTextField.addValueChangeListener(this); + listenedTextField.setImmediate(true); + changingTextField.setImmediate(true); + content.addComponent(dummyButton); + content.addComponent(listenedTextField); + content.addComponent(changingTextField); + content.setMargin(true); + content.setSpacing(true); + setContent(content); + } + + @Override + protected String getTestDescription() { + return "Check that creating or removing caption wrap doesn't lose focus"; + } + + @Override + protected Integer getTicketNumber() { + return 12967; + } + + @Override + public void valueChange(ValueChangeEvent event) { + changingTextField.setRequired(!changingTextField.isRequired()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java new file mode 100644 index 0000000000..14c26a0e17 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/orderedlayout/VerticalLayoutFocusWithDOMChangesTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.orderedlayout; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.By; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class VerticalLayoutFocusWithDOMChangesTest extends MultiBrowserTest { + + private String initialText = "Some"; + private String incrementalText = " text"; + + @Test + public void inputTextAndChangeFocus() throws InterruptedException { + openTestURL(); + List<WebElement> textFields = getDriver().findElements( + By.tagName("input")); + WebElement tf1 = textFields.get(0); + WebElement tf2 = textFields.get(1); + tf1.sendKeys(initialText); + new Actions(getDriver()).moveToElement(tf2).click().build().perform(); + + WebElement activeElement = getFocusedElement(); + Assert.assertEquals("input", activeElement.getTagName()); + Assert.assertEquals("", activeElement.getAttribute("value")); + + tf1.sendKeys(incrementalText); + new Actions(getDriver()) + .moveToElement( + getDriver().findElement(By.className("v-button"))) + .click().build().perform(); + activeElement = getFocusedElement(); + Assert.assertEquals("Just a button", activeElement.getText()); + + DesiredCapabilities capabilities = getDesiredCapabilities(); + if (capabilities.equals(BrowserUtil.ie(8)) + || capabilities.equals(BrowserUtil.ie(9))) { + // IE8 and IE9 insert cursor in the start of input instead of end. + Assert.assertEquals(incrementalText + initialText, + tf1.getAttribute("value")); + } else { + Assert.assertEquals(initialText + incrementalText, + tf1.getAttribute("value")); + } + } + + @Test + public void moveFocusAndChangeFieldWithValue() { + openTestURL(); + List<WebElement> textFields = getDriver().findElements( + By.tagName("input")); + WebElement tf1 = textFields.get(0); + WebElement tf2 = textFields.get(1); + + String firstText = "This is"; + String secondText = " default value"; + + tf2.sendKeys(firstText); + tf1.sendKeys(initialText); + new Actions(getDriver()).moveToElement(tf2).click().build().perform(); + + WebElement activeElement = getFocusedElement(); + Assert.assertEquals("input", activeElement.getTagName()); + Assert.assertEquals(firstText, activeElement.getAttribute("value")); + + new Actions(getDriver()).sendKeys(secondText).build().perform(); + DesiredCapabilities capabilities = getDesiredCapabilities(); + if (capabilities.equals(BrowserUtil.ie(8)) + || capabilities.equals(BrowserUtil.ie(9))) { + // IE8 and IE9 insert cursor in the start of input instead of end. + Assert.assertEquals(secondText + firstText, + tf2.getAttribute("value")); + } else { + Assert.assertEquals(firstText + secondText, + tf2.getAttribute("value")); + } + } + +} diff --git a/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html new file mode 100644 index 0000000000..2f8532de61 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.html @@ -0,0 +1,47 @@ +<?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>SelectItemCaptionRefresh</title> +</head> +<body> +<table cellpadding="1" cellspacing="1" border="1"> +<thead> +<tr><td rowspan="1" colspan="3">SelectItemCaptionRefresh</td></tr> +</thead><tbody> +<tr> + <td>open</td> + <td>/run/com.vaadin.tests.components.select.SelectItemCaptionRefresh?restartApplication</td> + <td></td> +</tr> +<tr> + <td>mouseClick</td> + <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#button</td> + <td>10,14</td> +</tr> +<tr> + <td>mouseClick</td> + <td>//div[@id='VAADIN_COMBOBOX_OPTIONLIST']/div/div[2]/table/tbody/tr[2]/td/span</td> + <td>16,11</td> +</tr> +<tr> + <td>verifyValue</td> + <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#textbox</td> + <td>start</td> +</tr> +<tr> + <td>click</td> + <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VButton[0]/domChild[0]</td> + <td></td> +</tr> +<tr> + <td>verifyValue</td> + <td>vaadin=runcomvaadintestscomponentsselectSelectItemCaptionRefresh::/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[0]/VFilterSelect[0]#textbox</td> + <td>0</td> +</tr> + +</tbody></table> +</body> +</html> diff --git a/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java new file mode 100644 index 0000000000..de068ed230 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/select/SelectItemCaptionRefresh.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.select; + +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.Select; + +public class SelectItemCaptionRefresh extends AbstractTestUI { + + final Object itemId = new Object(); + Select select; + + Button.ClickListener clickListener = new Button.ClickListener() { + Integer i = Integer.valueOf(0); + + @Override + public void buttonClick(final ClickEvent event) { + select.setItemCaption(itemId, (i++).toString()); + } + }; + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. + * VaadinRequest) + */ + @Override + protected void setup(VaadinRequest request) { + select = new Select("Foo"); + + select.addItem(itemId); + select.setItemCaption(itemId, "start"); + + addComponent(select); + addComponent(new Button("Update item's caption", clickListener)); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() + */ + @Override + protected String getTestDescription() { + return "Selected option should be updated when item caption changes in the Select."; + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() + */ + @Override + protected Integer getTicketNumber() { + return 9250; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.java b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetset.java index e837321b56..f674567a2d 100644 --- a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.java +++ b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetset.java @@ -6,11 +6,13 @@ import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent; @Widgetset("com.vaadin.tests.widgetset.TestingWidgetSet") -public class TestUIWidgetset extends AbstractTestUI { +public class ComponentIncludedInCustomWidgetset extends AbstractTestUI { @Override protected void setup(VaadinRequest request) { - addComponent(new MissingFromDefaultWidgetsetComponent()); + MissingFromDefaultWidgetsetComponent component = new MissingFromDefaultWidgetsetComponent(); + component.setId("missing-component"); + addComponent(component); } @Override diff --git a/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.java b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.java new file mode 100644 index 0000000000..f27ef5d789 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComponentIncludedInCustomWidgetsetTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Tests if a component is included in a custom widgetset + * (com.vaadin.tests.widgetset.TestingWidgetSet) + * + * @author Vaadin Ltd + */ +public class ComponentIncludedInCustomWidgetsetTest extends MultiBrowserTest { + + @Test + public void testComponentInTestingWidgetsetNotInDefaultWidgetset() { + openTestURL(); + WebElement component = vaadinElementById("missing-component"); + assertEquals( + "This component is available in TestingWidgetset, but not in DefaultWidgetset", + component.getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset2.java b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetset.java index a68cd91a5e..554a461c37 100644 --- a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset2.java +++ b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetset.java @@ -4,11 +4,13 @@ import com.vaadin.server.VaadinRequest; import com.vaadin.tests.components.AbstractTestUI; import com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent; -public class TestUIWidgetset2 extends AbstractTestUI { +public class ComponentMissingFromDefaultWidgetset extends AbstractTestUI { @Override protected void setup(VaadinRequest request) { - addComponent(new MissingFromDefaultWidgetsetComponent()); + MissingFromDefaultWidgetsetComponent component = new MissingFromDefaultWidgetsetComponent(); + component.setId("missing-component"); + addComponent(component); } @Override diff --git a/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java new file mode 100644 index 0000000000..ec8add75e0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/ui/ComponentMissingFromDefaultWidgetsetTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.ui; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * Test for testing if a component is missing from a widgetset. + * + * @author Vaadin Ltd + */ +public class ComponentMissingFromDefaultWidgetsetTest extends MultiBrowserTest { + + @Test + public void testComponentInTestingWidgetset() { + openTestURL(); + WebElement component = vaadinElementById("missing-component"); + assertTrue(component + .getText() + .startsWith( + "Widgetset 'com.vaadin.DefaultWidgetSet' does not contain implementation for com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent.")); + + } +} diff --git a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html b/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html deleted file mode 100644 index 4c10dc4275..0000000000 --- a/uitest/src/com/vaadin/tests/components/ui/TestUIWidgetset.html +++ /dev/null @@ -1,36 +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>Ticket4607</title> -</head> -<body> -<table cellpadding="1" cellspacing="1" border="1"> -<thead> -<tr><td rowspan="1" colspan="3">Ticket4607</td></tr> -</thead><tbody> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.ui.TestUIWidgetset?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsuiTestUIWidgetset::/VVerticalLayout[0]/VVerticalLayout[0]/VLabel[0]</td> - <td>This component is available in TestingWidgetset, but not in DefaultWidgetset</td> -</tr> -<tr> - <td>open</td> - <td>/run/com.vaadin.tests.components.ui.TestUIWidgetset2?restartApplication</td> - <td></td> -</tr> -<tr> - <td>assertText</td> - <td>vaadin=runcomvaadintestscomponentsuiTestUIWidgetset2::/VVerticalLayout[0]/VVerticalLayout[0]/VUnknownComponent[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]</td> - <td>Widgetset does not contain implementation for com.vaadin.tests.widgetset.server.MissingFromDefaultWidgetsetComponent. Check its component connector's @Connect mapping, widgetsets GWT module description file and re-compile your widgetset. In case you have downloaded a vaadin add-on package, you might want to refer to add-on instructions.</td> -</tr> -</tbody></table> -</body> -</html> diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index f6fce18fae..55a2b80918 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -28,9 +28,13 @@ import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.HasInputDevices; +import org.openqa.selenium.interactions.Keyboard; +import org.openqa.selenium.interactions.Mouse; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; @@ -275,6 +279,21 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } /** + * Uses JavaScript to determine the currently focused element. + * + * @return Focused element or null + */ + protected WebElement getFocusedElement() { + Object focusedElement = ((JavascriptExecutor) getDriver()) + .executeScript("return document.activeElement"); + if (null != focusedElement) { + return (WebElement) focusedElement; + } else { + return null; + } + } + + /** * Find a Vaadin element based on its id given using Component.setId * * @param id @@ -891,4 +910,22 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { } + /** + * Returns the mouse object for doing mouse commands + * + * @return Returns the mouse + */ + public Mouse getMouse() { + return ((HasInputDevices) getDriver()).getMouse(); + } + + /** + * Returns the keyboard object for controlling keyboard events + * + * @return Return the keyboard + */ + public Keyboard getKeyboard() { + return ((HasInputDevices) getDriver()).getKeyboard(); + } + } |