aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bom/pom.xml5
-rw-r--r--ivysettings.xml2
-rw-r--r--pom.xml1
-rw-r--r--test/pom.xml2
-rw-r--r--testbench-api/pom.xml54
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbsoluteLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractColorPickerElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentContainerElement.java24
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentElement.java84
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractEmbeddedElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractFieldElement.java50
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractJavaScriptComponentElement.java24
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractMediaElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractOrderedLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSelectElement.java31
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSingleComponentContainerElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSplitPanelElement.java86
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractTextFieldElement.java50
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AccordionElement.java31
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/AudioElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/BrowserFrameElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ButtonElement.java59
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CalendarElement.java74
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxElement.java90
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxGroupElement.java94
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerAreaElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerElement.java30
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerPreviewElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ComboBoxElement.java233
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CssLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CustomComponentElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CustomFieldElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/CustomLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/DateFieldElement.java62
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/EmbeddedElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/FlashElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/FormElement.java24
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/FormLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java444
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/GridLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalSplitPanelElement.java31
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ImageElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/InlineDateFieldElement.java42
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/LabelElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/LegacyWindowElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/LinkElement.java39
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ListSelectElement.java119
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/MenuBarElement.java168
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/NativeButtonElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/NativeSelectElement.java75
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/NotificationElement.java100
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/OptionGroupElement.java95
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/PanelElement.java35
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/PasswordFieldElement.java32
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/PopupDateFieldElement.java24
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/PopupViewElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressBarElement.java42
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressIndicatorElement.java24
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/RadioButtonGroupElement.java94
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/RichTextAreaElement.java22
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/SelectElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/SliderElement.java57
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TabSheetElement.java210
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TableElement.java150
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TableHeaderElement.java43
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TableRowElement.java49
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TextAreaElement.java46
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TextFieldElement.java25
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TreeElement.java43
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableElement.java31
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableRowElement.java36
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/TwinColSelectElement.java134
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/UIElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/UploadElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalLayoutElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalSplitPanelElement.java31
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/VideoElement.java23
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/elements/WindowElement.java94
-rw-r--r--testbench-api/src/main/java/com/vaadin/testbench/exceptions/NoSuchColumnException.java20
-rw-r--r--uitest-common/pom.xml3
-rw-r--r--uitest/ivy.xml4
83 files changed, 4157 insertions, 5 deletions
diff --git a/bom/pom.xml b/bom/pom.xml
index c9b7178305..b6387da3f4 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -90,6 +90,11 @@
<artifactId>vaadin-compatibility-client-compiled</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.vaadin</groupId>
+ <artifactId>vaadin-testbench-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- AddOn Dependencies -->
<dependency>
diff --git a/ivysettings.xml b/ivysettings.xml
index 39da2e5efb..f28250c3c1 100644
--- a/ivysettings.xml
+++ b/ivysettings.xml
@@ -34,7 +34,7 @@
<module organisation="com.vaadin" name="vaadin-testbench-core"
resolver="vaadin-addons" />
<module organisation="com.vaadin" name="vaadin-testbench-api"
- resolver="vaadin-addons" />
+ resolver="vaadin-maven" />
<module organisation="com.vaadin" name="vaadin-buildhelpers"
resolver="vaadin-maven" />
<module organisation="com.vaadin" name="vaadin-root"
diff --git a/pom.xml b/pom.xml
index 4f2fde4809..7d14fc9c75 100644
--- a/pom.xml
+++ b/pom.xml
@@ -565,6 +565,7 @@
<module>compatibility-client-compiled</module>
<module>compatibility-shared</module>
<module>compatibility-themes</module>
+ <module>testbench-api</module>
<!-- Nexus staging bug needs the last module to be deployed. -->
<module>bom</module>
</modules>
diff --git a/test/pom.xml b/test/pom.xml
index f9a38d0592..d5502dc6e9 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -64,7 +64,7 @@
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
- <artifactId>vaadin-testbench</artifactId>
+ <artifactId>vaadin-testbench-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
diff --git a/testbench-api/pom.xml b/testbench-api/pom.xml
new file mode 100644
index 0000000000..c7cc8ccfe4
--- /dev/null
+++ b/testbench-api/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.vaadin</groupId>
+ <artifactId>vaadin-root</artifactId>
+ <version>8.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>vaadin-testbench-api</artifactId>
+ <name>vaadin-testbench-api</name>
+ <packaging>jar</packaging>
+
+ <url>https://vaadin.com/</url>
+ <description>Vaadin Framework Element API for TestBench</description>
+
+ <properties>
+ <testbench.core.version>5.0.0.alpha2</testbench.core.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.vaadin</groupId>
+ <artifactId>vaadin-testbench-core</artifactId>
+ <version>${testbench.core.version}</version>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>vaadin-addons</id>
+ <url>http://maven.vaadin.com/vaadin-addons</url>
+ </repository>
+ </repositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>checkstyle</goal>
+ </goals>
+ <phase>process-sources</phase>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+
+</project>
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbsoluteLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbsoluteLayoutElement.java
new file mode 100644
index 0000000000..26620b0af0
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbsoluteLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbsoluteLayout")
+public class AbsoluteLayoutElement extends AbstractLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractColorPickerElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractColorPickerElement.java
new file mode 100644
index 0000000000..6f6631a52b
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractColorPickerElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractColorPicker")
+public class AbstractColorPickerElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentContainerElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentContainerElement.java
new file mode 100644
index 0000000000..5224920470
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentContainerElement.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractComponentContainer")
+public class AbstractComponentContainerElement
+ extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentElement.java
new file mode 100644
index 0000000000..9b4a4344f8
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractComponentElement.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elementsbase.AbstractElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractComponent")
+public class AbstractComponentElement extends AbstractElement {
+ /**
+ * Returns the caption of the Component element
+ *
+ * @since
+ * @return
+ */
+ public String getCaption() {
+ final String GWT_ID_ATTRIBUTE = "aria-labelledby";
+ WebElement captElem = null;
+ String captionId = null;
+ captionId = getAttribute(GWT_ID_ATTRIBUTE);
+ // IE8 getAttribute returns empty string instead of null
+ // when there is no attribute with specified name
+ if (captionId == null || captionId.equals("")) {
+ WebElement elem = findElement(
+ By.xpath(".//*[@" + GWT_ID_ATTRIBUTE + "]"));
+ captionId = elem.getAttribute(GWT_ID_ATTRIBUTE);
+ }
+ // element ids are unique, we can search the whole page
+ captElem = getDriver().findElement(By.id(captionId));
+ return captElem.getText();
+ }
+
+ public String getHTML() {
+ return getWrappedElement().getAttribute("innerHTML");
+ }
+
+ public boolean isReadOnly() {
+ final String READONLY_CSS_CLASS = "v-readonly";
+ String readonlyClass = getAttribute("class");
+ // lookin for READONLY_CSS_CLASS string
+ String[] cssSelectors = readonlyClass.split("\\s");
+ for (String selector : cssSelectors) {
+ if (selector.equals(READONLY_CSS_CLASS)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected String getStyleAttribute(WebElement element, String styleName) {
+ String style = element.getAttribute("style");
+
+ String[] styles = style.split(";");
+ for (String stylePart : styles) {
+ // IE8 has uppercased styles
+ String lowercasePart = stylePart.toLowerCase();
+ if (lowercasePart.startsWith(styleName + ":")) {
+ return lowercasePart.substring(styleName.length() + 1).trim();
+ }
+ }
+
+ return null;
+ }
+
+ public class ReadOnlyException extends RuntimeException {
+
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractEmbeddedElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractEmbeddedElement.java
new file mode 100644
index 0000000000..406b42db35
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractEmbeddedElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractEmbedded")
+public class AbstractEmbeddedElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractFieldElement.java
new file mode 100644
index 0000000000..3980d263d8
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractFieldElement.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractField")
+public class AbstractFieldElement extends AbstractComponentElement {
+
+ /**
+ * Select contents of TextField Element
+ *
+ * NOTE: When testing with firefox browser window should have focus in it
+ *
+ * @since
+ * @param elem
+ * element which context will be select
+ */
+ protected void clientSelectElement(WebElement elem) {
+ JavascriptExecutor js = (JavascriptExecutor) getDriver();
+ String script = "window.focus();" + "var elem=arguments[0];"
+ + "elem.select();elem.focus();";
+ js.executeScript(script, elem);
+ }
+
+ protected void clearElementClientSide(WebElement elem) {
+ // clears without triggering an event (on client side)
+ JavascriptExecutor js = (JavascriptExecutor) getDriver();
+ String script = "window.focus(); var elem=arguments[0];"
+ + "elem.value=\"\";";
+ js.executeScript(script, elem);
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractJavaScriptComponentElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractJavaScriptComponentElement.java
new file mode 100644
index 0000000000..9cf17ece9c
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractJavaScriptComponentElement.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractJavaScriptComponent")
+public class AbstractJavaScriptComponentElement
+ extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractLayoutElement.java
new file mode 100644
index 0000000000..08d9fe4f6e
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractLayout")
+public class AbstractLayoutElement extends AbstractComponentContainerElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractMediaElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractMediaElement.java
new file mode 100644
index 0000000000..dad016fdc1
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractMediaElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractMedia")
+public class AbstractMediaElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractOrderedLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractOrderedLayoutElement.java
new file mode 100644
index 0000000000..35bdd15ae1
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractOrderedLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractOrderedLayout")
+public class AbstractOrderedLayoutElement extends AbstractLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSelectElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSelectElement.java
new file mode 100644
index 0000000000..cb90f238b2
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSelectElement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractSelect")
+public class AbstractSelectElement extends AbstractFieldElement {
+
+ /**
+ * Clear operation is not supported for select element classes. This
+ * operation has no effect on select element
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSingleComponentContainerElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSingleComponentContainerElement.java
new file mode 100644
index 0000000000..5dffcdad06
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSingleComponentContainerElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractSingleComponentContainer")
+public class AbstractSingleComponentContainerElement
+ extends AbstractComponentElement {
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSplitPanelElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSplitPanelElement.java
new file mode 100644
index 0000000000..7e5ed87c5e
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractSplitPanelElement.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBench;
+import com.vaadin.testbench.elementsbase.AbstractElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractSplitPanel")
+public class AbstractSplitPanelElement
+ extends AbstractComponentContainerElement {
+
+ private static org.openqa.selenium.By byFirstContainer = By
+ .xpath("./div/div[contains(normalize-space(concat(@class, ' ')), "
+ + "normalize-space('-first-container '))]/*");
+ private static org.openqa.selenium.By bySecondContainer = By
+ .xpath("./div/div[contains(normalize-space(concat(@class, ' ')), "
+ + "normalize-space('-second-container '))]/*");
+
+ /**
+ * Gets the first component of a split panel and wraps it in given class.
+ *
+ * @param clazz
+ * Components element class
+ * @return First component wrapped in given class
+ */
+ public <T extends AbstractElement> T getFirstComponent(Class<T> clazz) {
+ return getContainedComponent(clazz, byFirstContainer);
+ }
+
+ /**
+ * Gets the second component of a split panel and wraps it in given class.
+ *
+ * @param clazz
+ * Components element class
+ * @return Second component wrapped in given class
+ */
+ public <T extends AbstractElement> T getSecondComponent(Class<T> clazz) {
+ return getContainedComponent(clazz, bySecondContainer);
+ }
+
+ /**
+ * Gets a component of a split panel and wraps it in the given class.
+ *
+ * @param clazz
+ * Components element class
+ * @param byContainer
+ * A locator that specifies the container (first or second) whose
+ * component is looked for
+ * @return A component wrapped in the given class
+ */
+ private <T extends AbstractElement> T getContainedComponent(Class<T> clazz,
+ org.openqa.selenium.By byContainer) {
+ List<AbstractComponentElement> containedComponents = $$(
+ AbstractComponentElement.class).all();
+ List<WebElement> componentsInSelectedContainer = findElements(
+ byContainer);
+ for (AbstractComponentElement component : containedComponents) {
+ WebElement elem = component.getWrappedElement();
+ if (componentsInSelectedContainer.contains(elem)) {
+ return TestBench.createElement(clazz, elem,
+ getCommandExecutor());
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractTextFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractTextFieldElement.java
new file mode 100644
index 0000000000..6435f4a096
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AbstractTextFieldElement.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.AbstractTextField")
+public class AbstractTextFieldElement extends AbstractFieldElement {
+
+ /**
+ * Return value of the field element
+ *
+ * @return value of the field element
+ */
+ public String getValue() {
+ return findElement(By.tagName("input")).getAttribute("value");
+ }
+
+ /**
+ * Set value of the field element
+ *
+ * @param chars
+ * new value of the field
+ */
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ clearElementClientSide(this);
+ focus();
+ sendKeys(chars);
+ sendKeys(Keys.TAB);
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AccordionElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AccordionElement.java
new file mode 100644
index 0000000000..f8a2451e1e
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AccordionElement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Accordion")
+public class AccordionElement extends TabSheetElement {
+
+ {
+ // Only difference in using Accordion vs. TabSheet is CSS class name for
+ // items
+ byTabCell = By.className("v-accordion-item");
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/AudioElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/AudioElement.java
new file mode 100644
index 0000000000..60164e2913
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/AudioElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Audio")
+public class AudioElement extends AbstractMediaElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/BrowserFrameElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/BrowserFrameElement.java
new file mode 100644
index 0000000000..a27a08449c
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/BrowserFrameElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.BrowserFrame")
+public class BrowserFrameElement extends AbstractEmbeddedElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ButtonElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ButtonElement.java
new file mode 100644
index 0000000000..5da9753367
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ButtonElement.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Button")
+public class ButtonElement extends AbstractComponentElement {
+
+ @Override
+ public String getCaption() {
+ WebElement captElem = findElement(By.className("v-button-caption"));
+ return captElem.getText();
+ }
+
+ private boolean tryClickChild(WebElement e) {
+ List<WebElement> children = e.findElements(By.xpath(".//*"));
+ for (WebElement c : children) {
+ if (c.isDisplayed()) {
+ c.click();
+ return true;
+ } else {
+ if (tryClickChild(c)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void click() {
+ if (!isDisplayed()) {
+ if (tryClickChild(this)) {
+ return;
+ }
+ }
+
+ super.click();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CalendarElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CalendarElement.java
new file mode 100644
index 0000000000..bd1c3c53e5
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CalendarElement.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Calendar")
+@Deprecated
+public class CalendarElement extends AbstractComponentElement {
+ public List<WebElement> getWeekNumbers() {
+ return findElements(By.className("v-calendar-week-number"));
+ }
+
+ public boolean hasMonthView() {
+ return isElementPresent(By.className("v-calendar-week-numbers"));
+ }
+
+ public boolean hasWeekView() {
+ return isElementPresent(By.className("v-calendar-header-week"));
+ }
+
+ public List<WebElement> getDayNumbers() {
+ return findElements(By.className("v-calendar-day-number"));
+ }
+
+ public List<WebElement> getMonthDays() {
+ return findElements(By.className("v-calendar-month-day"));
+ }
+
+ public boolean hasDayView() {
+ return getDayHeaders().size() == 1;
+ }
+
+ public List<WebElement> getDayHeaders() {
+ return findElements(By.className("v-calendar-header-day"));
+ }
+
+ public void back() {
+ if (hasWeekView() || hasDayView()) {
+ findElement(By.className("v-calendar-back")).click();
+ } else {
+ throw new IllegalStateException(
+ "Navigation only available in week or day view");
+ }
+ }
+
+ public void next() {
+ if (hasWeekView() || hasDayView()) {
+ findElement(By.className("v-calendar-next")).click();
+ } else {
+ throw new IllegalStateException(
+ "Navigation only available in week or day view");
+ }
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxElement.java
new file mode 100644
index 0000000000..6263ce5b0f
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxElement.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.commands.TestBenchElementCommands;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.CheckBox")
+public class CheckBoxElement extends AbstractFieldElement {
+
+ /**
+ * Return string representation of value of the checkbox Return either
+ * checked or unchecked
+ */
+ public String getValue() {
+ if (isChecked()) {
+ return "checked";
+ } else {
+ return "unchecked";
+ }
+ }
+
+ /**
+ * Checks if the checkbox is checked.
+ *
+ * @return <code>true</code> if the checkbox is checked, <code>false</code>
+ * otherwise.
+ */
+ public boolean isChecked() {
+ return getInputElement().isSelected();
+ }
+
+ /**
+ * Clears the check box, setting unchecked value. The check box is unchecked
+ * by sending a click event on it.
+ *
+ */
+ @Override
+ public void clear() {
+ if (isChecked()) {
+ click();
+ }
+ }
+
+ @Override
+ public String getCaption() {
+ WebElement elem = findElement(By.xpath(".."))
+ .findElement(By.tagName("label"));
+ return elem.getText();
+ }
+
+ @Override
+ public void click() {
+ WebElement input = getInputElement();
+ if (isFirefox()) {
+ // When using Valo, the input element is covered by a
+ // pseudo-element, which Firefox will complain about
+ getCommandExecutor().executeScript("arguments[0].click()", input);
+ } else if (isChrome()) {
+ ((TestBenchElementCommands) (input)).click(0, 0);
+ } else {
+ input.click();
+ }
+ }
+
+ /**
+ * Gets the &lt;input&gt; element of the checkbox.
+ *
+ * @return the input element
+ */
+ public WebElement getInputElement() {
+ return findElement(By.tagName("input"));
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxGroupElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxGroupElement.java
new file mode 100644
index 0000000000..ed657c085d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CheckBoxGroupElement.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.CheckBoxGroup")
+public class CheckBoxGroupElement extends AbstractSelectElement {
+
+ private static org.openqa.selenium.By bySelectOption = By
+ .className("v-select-option");
+ private static org.openqa.selenium.By byLabel = By.tagName("label");
+ private static org.openqa.selenium.By byRadioInput = By.tagName("input");
+
+ public List<String> getOptions() {
+ List<String> optionTexts = new ArrayList<String>();
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ optionTexts.add(option.findElement(byLabel).getText());
+ }
+ return optionTexts;
+ }
+
+ public void selectByText(String text) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ if (text.equals(option.findElement(byLabel).getText())) {
+ WebElement input = option.findElement(byRadioInput);
+ ((TestBenchElement) (input)).clickHiddenElement();
+ }
+ }
+ }
+
+ /**
+ * Return value of the selected option in the option group
+ *
+ * @return value of the selected option in the option group
+ */
+ public String getValue() {
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ WebElement checkedItem;
+ checkedItem = option.findElement(By.tagName("input"));
+ String checked = checkedItem.getAttribute("checked");
+ if (checked != null
+ && checkedItem.getAttribute("checked").equals("true")) {
+ return option.findElement(By.tagName("label")).getText();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Select option in the option group with the specified value
+ *
+ * @param chars
+ * value of the option in the option group which will be selected
+ */
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ selectByText((String) chars);
+ }
+
+ /**
+ * Clear operation is not supported for Option Group. This operation has no
+ * effect on Option Group element.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerAreaElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerAreaElement.java
new file mode 100644
index 0000000000..9679ee839d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerAreaElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ColorPickerArea")
+public class ColorPickerAreaElement extends AbstractColorPickerElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerElement.java
new file mode 100644
index 0000000000..bbbfe79af9
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerElement.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ColorPicker")
+public class ColorPickerElement extends AbstractColorPickerElement {
+ @Override
+ public String getCaption() {
+ WebElement captElem = findElement(By.className("v-button-caption"));
+ return captElem.getText();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerPreviewElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerPreviewElement.java
new file mode 100644
index 0000000000..62a91eb50c
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ColorPickerPreviewElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ColorPickerPreview")
+public class ColorPickerPreviewElement extends CssLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ComboBoxElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ComboBoxElement.java
new file mode 100644
index 0000000000..980c4a1e7f
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ComboBoxElement.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.NoSuchElementException;
+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 AbstractSelectElement {
+
+ private static org.openqa.selenium.By bySuggestionPopup = By
+ .vaadin("#popup");
+ private static org.openqa.selenium.By byNextPage = By
+ .className("v-filterselect-nextpage");
+ private static org.openqa.selenium.By byPrevPage = By
+ .className("v-filterselect-prevpage");
+
+ /**
+ * Selects the first option in the ComboBox which matches the given text.
+ *
+ * @param text
+ * the text of the option to select
+ */
+ public void selectByText(String text) {
+ if (!isTextInputAllowed()) {
+ selectByTextFromPopup(text);
+ return;
+ }
+ getInputField().clear();
+ sendInputFieldKeys(text);
+
+ selectSuggestion(text);
+ }
+
+ /**
+ * Selects, without filtering, the first option in the ComboBox which
+ * matches the given text.
+ *
+ * @param text
+ * the text of the option to select
+ */
+ private void selectByTextFromPopup(String text) {
+ // This method assumes there is no need to touch the filter string
+
+ // 1. Find first page
+ // 2. Select first matching text if found
+ // 3. Iterate towards end
+
+ while (openPrevPage()) {
+ // Scroll until beginning
+ }
+
+ do {
+ if (selectSuggestion(text)) {
+ return;
+ }
+ } while (openNextPage());
+ }
+
+ private boolean selectSuggestion(String text) {
+ for (WebElement suggestion : getPopupSuggestionElements()) {
+ if (text.equals(suggestion.getText())) {
+ suggestion.click();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isReadOnly(WebElement elem) {
+ JavascriptExecutor js = (JavascriptExecutor) getDriver();
+ return (Boolean) js.executeScript("return arguments[0].readOnly", elem);
+ }
+
+ /**
+ * Checks if text input is allowed for the combo box.
+ *
+ * @return <code>true</code> if text input is allowed, <code>false</code>
+ * otherwise
+ */
+ public boolean isTextInputAllowed() {
+ return !isReadOnly(getInputField());
+ }
+
+ /*
+ * Workaround selenium's bug: sendKeys() will not send left parentheses
+ * properly. See #14048.
+ */
+ private void sendInputFieldKeys(String text) {
+ WebElement textBox = getInputField();
+ if (!text.contains("(")) {
+ textBox.sendKeys(text);
+ return;
+ }
+
+ String OPEN_PARENTHESES = "_OPEN_PARENT#H#ESES_";
+ String tamperedText = text.replaceAll("\\(", OPEN_PARENTHESES);
+ textBox.sendKeys(tamperedText);
+
+ JavascriptExecutor js = getCommandExecutor();
+ String jsScript = String.format(
+ "arguments[0].value = arguments[0].value.replace(/%s/g, '(')",
+ OPEN_PARENTHESES);
+ js.executeScript(jsScript, textBox);
+
+ // refresh suggestions popupBox
+ textBox.sendKeys("a" + Keys.BACK_SPACE);
+ }
+
+ /**
+ * Open the suggestion popup
+ */
+ public void openPopup() {
+ findElement(By.vaadin("#button")).click();
+ }
+
+ /**
+ * Gets the text representation of all suggestions on the current page
+ *
+ * @return List of suggestion texts
+ */
+ public List<String> getPopupSuggestions() {
+ List<String> suggestionsTexts = new ArrayList<String>();
+ List<WebElement> suggestions = getPopupSuggestionElements();
+ for (WebElement suggestion : suggestions) {
+ String text = suggestion.getText();
+ if (!text.isEmpty()) {
+ suggestionsTexts.add(text);
+ }
+ }
+ return suggestionsTexts;
+ }
+
+ /**
+ * Gets the elements of all suggestions on the current page.
+ * <p>
+ * Opens the popup if not already open.
+ *
+ * @return a list of elements for the suggestions on the current page
+ */
+ public List<WebElement> getPopupSuggestionElements() {
+ List<WebElement> tables = getSuggestionPopup()
+ .findElements(By.tagName("table"));
+ if (tables == null || tables.isEmpty()) {
+ return Collections.emptyList();
+ }
+ WebElement table = tables.get(0);
+ return table.findElements(By.tagName("td"));
+ }
+
+ /**
+ * Opens next popup page.
+ *
+ * @return True if next page opened. false if doesn't have next page
+ */
+ public boolean openNextPage() {
+ try {
+ getSuggestionPopup().findElement(byNextPage).click();
+ return true;
+ } catch (NoSuchElementException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Open previous popup page.
+ *
+ * @return True if previous page opened. False if doesn't have previous page
+ */
+ public boolean openPrevPage() {
+ try {
+ getSuggestionPopup().findElement(byPrevPage).click();
+ return true;
+ } catch (NoSuchElementException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the suggestion popup element
+ */
+ public WebElement getSuggestionPopup() {
+ ensurePopupOpen();
+ return findElement(bySuggestionPopup);
+ }
+
+ /**
+ * Return value of the combo box element
+ *
+ * @return value of the combo box element
+ */
+ public String getValue() {
+ return getInputField().getAttribute("value");
+ }
+
+ /**
+ * Returns the text input field element, used for entering text into the
+ * combo box.
+ *
+ * @return the input field element
+ */
+ public WebElement getInputField() {
+ return findElement(By.xpath("input"));
+ }
+
+ private void ensurePopupOpen() {
+ if (!isElementPresent(bySuggestionPopup)) {
+ openPopup();
+ }
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CssLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CssLayoutElement.java
new file mode 100644
index 0000000000..fdf54e4f00
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CssLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.CssLayout")
+public class CssLayoutElement extends AbstractLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomComponentElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomComponentElement.java
new file mode 100644
index 0000000000..05c2b64045
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomComponentElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.CustomComponent")
+public class CustomComponentElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomFieldElement.java
new file mode 100644
index 0000000000..3d6ff9a5f1
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomFieldElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.CustomField")
+public class CustomFieldElement extends AbstractFieldElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomLayoutElement.java
new file mode 100644
index 0000000000..4ae4170c24
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/CustomLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.CustomLayout")
+public class CustomLayoutElement extends AbstractLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/DateFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/DateFieldElement.java
new file mode 100644
index 0000000000..740e2a6a68
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/DateFieldElement.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.DateField")
+public class DateFieldElement extends AbstractFieldElement {
+
+ /**
+ * Clear DateField element
+ */
+ @Override
+ public void clear() {
+ WebElement elem = findElement(By.tagName("input"));
+ elem.clear();
+ }
+
+ /**
+ * Return value of the date field element
+ *
+ * @return value of the date field element
+ */
+ public String getValue() {
+ return findElement(By.tagName("input")).getAttribute("value");
+ }
+
+ /**
+ * Set value of the date field element
+ *
+ * @param chars
+ * new value of the date field
+ */
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ WebElement elem = findElement(By.tagName("input"));
+ TestBenchElement tbElement = (TestBenchElement) elem;
+ clearElementClientSide(tbElement);
+ tbElement.sendKeys(chars);
+ tbElement.sendKeys(Keys.TAB);
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/EmbeddedElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/EmbeddedElement.java
new file mode 100644
index 0000000000..92225b4da7
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/EmbeddedElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Embedded")
+public class EmbeddedElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/FlashElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/FlashElement.java
new file mode 100644
index 0000000000..f0c5ef525c
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/FlashElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Flash")
+public class FlashElement extends AbstractEmbeddedElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/FormElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/FormElement.java
new file mode 100644
index 0000000000..2f4ebd1980
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/FormElement.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Form")
+@Deprecated
+public class FormElement extends AbstractFieldElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/FormLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/FormLayoutElement.java
new file mode 100644
index 0000000000..b3ef17046d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/FormLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.FormLayout")
+public class FormLayoutElement extends AbstractOrderedLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java
new file mode 100644
index 0000000000..f4959e1531
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/GridElement.java
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.openqa.selenium.NoSuchElementException;
+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
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+@ServerClass("com.vaadin.ui.Grid")
+public class GridElement extends AbstractComponentElement {
+
+ public static class GridCellElement extends AbstractElement {
+
+ private static final String FOCUSED_CELL_CLASS_NAME = "-cell-focused";
+ private static final String FROZEN_CLASS_NAME = "frozen";
+
+ public boolean isFocused() {
+ return getAttribute("class").contains(FOCUSED_CELL_CLASS_NAME);
+ }
+
+ public boolean isFrozen() {
+ return getAttribute("class").contains(FROZEN_CLASS_NAME);
+ }
+ }
+
+ public static class GridRowElement extends AbstractElement {
+
+ private static final String FOCUSED_CLASS_NAME = "-row-focused";
+ private static final String SELECTED_CLASS_NAME = "-row-selected";
+
+ public boolean isFocused() {
+ return getAttribute("class").contains(FOCUSED_CLASS_NAME);
+ }
+
+ @Override
+ public boolean isSelected() {
+ return getAttribute("class").contains(SELECTED_CLASS_NAME);
+ }
+
+ public GridCellElement getCell(int columnIndex) {
+ TestBenchElement e = (TestBenchElement) findElement(
+ By.xpath("./td[" + (columnIndex + 1) + "]"));
+ return e.wrap(GridCellElement.class);
+ }
+ }
+
+ public static class GridEditorElement extends AbstractElement {
+
+ private GridElement grid;
+
+ private GridEditorElement setGrid(GridElement grid) {
+ this.grid = grid;
+ return this;
+ }
+
+ /**
+ * Gets the editor field for column in given index.
+ *
+ * @param colIndex
+ * the column index
+ * @return the editor field for given location
+ *
+ * @throws NoSuchElementException
+ * if {@code isEditable(colIndex) == false}
+ */
+ public TestBenchElement getField(int colIndex) {
+ return grid.getSubPart("#editor[" + colIndex + "]");
+ }
+
+ /**
+ * Gets whether the column with the given index is editable, that is,
+ * has an associated editor field.
+ *
+ * @param colIndex
+ * the column index
+ * @return {@code true} if the column has an editor field, {@code false}
+ * otherwise
+ */
+ public boolean isEditable(int colIndex) {
+ return grid
+ .isElementPresent(By.vaadin("#editor[" + colIndex + "]"));
+ }
+
+ /**
+ * Checks whether a field is marked with an error.
+ *
+ * @param colIndex
+ * column index
+ * @return <code>true</code> iff the field is marked with an error
+ */
+ public boolean isFieldErrorMarked(int colIndex) {
+ return getField(colIndex).getAttribute("class").contains("error");
+ }
+
+ /**
+ * Saves the fields of this editor.
+ * <p>
+ * <em>Note:</em> that this closes the editor making this element
+ * useless.
+ */
+ public void save() {
+ findElement(By.className("v-grid-editor-save")).click();
+ }
+
+ /**
+ * Cancels this editor.
+ * <p>
+ * <em>Note:</em> that this closes the editor making this element
+ * useless.
+ */
+ public void cancel() {
+ findElement(By.className("v-grid-editor-cancel")).click();
+ }
+
+ /**
+ * Gets the error message text, or <code>null</code> if no message is
+ * present.
+ */
+ public String getErrorMessage() {
+ WebElement messageWrapper = findElement(
+ By.className("v-grid-editor-message"));
+ List<WebElement> divs = messageWrapper
+ .findElements(By.tagName("div"));
+ if (divs.isEmpty()) {
+ return null;
+ } else {
+ return divs.get(0).getText();
+ }
+ }
+ }
+
+ /**
+ * Scrolls Grid element so that wanted row is displayed
+ *
+ * @param index
+ * Target row
+ */
+ public void scrollToRow(int index) {
+ try {
+ getSubPart("#cell[" + index + "]");
+ } catch (NoSuchElementException e) {
+ // Expected, ignore it.
+ }
+ }
+
+ /**
+ * Gets cell element with given row and column index.
+ *
+ * @param rowIndex
+ * Row index
+ * @param colIndex
+ * Column index
+ * @return Cell element with given indices.
+ */
+ public GridCellElement getCell(int rowIndex, int colIndex) {
+ scrollToRow(rowIndex);
+ return getSubPart("#cell[" + rowIndex + "][" + colIndex + "]")
+ .wrap(GridCellElement.class);
+ }
+
+ /**
+ * Gets row element with given row index.
+ *
+ * @param index
+ * Row index
+ * @return Row element with given index.
+ */
+ public GridRowElement getRow(int index) {
+ scrollToRow(index);
+ return getSubPart("#cell[" + index + "]").wrap(GridRowElement.class);
+ }
+
+ /**
+ * Gets header cell element with given row and column index.
+ *
+ * @param rowIndex
+ * Row index
+ * @param colIndex
+ * Column index
+ * @return Header cell element with given indices.
+ */
+ public GridCellElement getHeaderCell(int rowIndex, int colIndex) {
+ return getSubPart("#header[" + rowIndex + "][" + colIndex + "]")
+ .wrap(GridCellElement.class);
+ }
+
+ /**
+ * Gets footer cell element with given row and column index.
+ *
+ * @param rowIndex
+ * Row index
+ * @param colIndex
+ * Column index
+ * @return Footer cell element with given indices.
+ */
+ public GridCellElement getFooterCell(int rowIndex, int colIndex) {
+ return getSubPart("#footer[" + rowIndex + "][" + colIndex + "]")
+ .wrap(GridCellElement.class);
+ }
+
+ /**
+ * Gets list of header cell elements on given row.
+ *
+ * @param rowIndex
+ * Row index
+ * @return Header cell elements on given row.
+ */
+ public List<GridCellElement> getHeaderCells(int rowIndex) {
+ List<GridCellElement> headers = new ArrayList<GridCellElement>();
+ for (TestBenchElement e : TestBenchElement.wrapElements(
+ getSubPart("#header[" + rowIndex + "]").findElements(
+ By.xpath("./th")),
+ getCommandExecutor())) {
+ headers.add(e.wrap(GridCellElement.class));
+ }
+ return headers;
+ }
+
+ /**
+ * Gets list of header cell elements on given row.
+ *
+ * @param rowIndex
+ * Row index
+ * @return Header cell elements on given row.
+ */
+ public List<GridCellElement> getFooterCells(int rowIndex) {
+ List<GridCellElement> footers = new ArrayList<GridCellElement>();
+ for (TestBenchElement e : TestBenchElement.wrapElements(
+ getSubPart("#footer[" + rowIndex + "]").findElements(
+ By.xpath("./td")),
+ getCommandExecutor())) {
+ footers.add(e.wrap(GridCellElement.class));
+ }
+ return footers;
+ }
+
+ /**
+ * Get header row count
+ *
+ * @return Header row count
+ */
+ public int getHeaderCount() {
+ return getSubPart("#header").findElements(By.xpath("./tr")).size();
+ }
+
+ /**
+ * Get footer row count
+ *
+ * @return Footer row count
+ */
+ public int getFooterCount() {
+ return getSubPart("#footer").findElements(By.xpath("./tr")).size();
+ }
+
+ /**
+ * Get a header row by index
+ *
+ * @param rowIndex
+ * Row index
+ * @return The th element of the row
+ */
+ public TestBenchElement getHeaderRow(int rowIndex) {
+ return getSubPart("#header[" + rowIndex + "]");
+ }
+
+ /**
+ * Get a footer row by index
+ *
+ * @param rowIndex
+ * Row index
+ * @return The tr element of the row
+ */
+ public TestBenchElement getFooterRow(int rowIndex) {
+ return getSubPart("#footer[" + rowIndex + "]");
+ }
+
+ /**
+ * Get the vertical scroll element
+ *
+ * @return The element representing the vertical scrollbar
+ */
+ public TestBenchElement getVerticalScroller() {
+ List<WebElement> rootElements = findElements(By.xpath("./div"));
+ return (TestBenchElement) rootElements.get(0);
+ }
+
+ /**
+ * Get the horizontal scroll element
+ *
+ * @return The element representing the horizontal scrollbar
+ */
+ public TestBenchElement getHorizontalScroller() {
+ List<WebElement> rootElements = findElements(By.xpath("./div"));
+ return (TestBenchElement) rootElements.get(1);
+ }
+
+ /**
+ * Get the header element
+ *
+ * @return The thead element
+ */
+ public TestBenchElement getHeader() {
+ return getSubPart("#header");
+ }
+
+ /**
+ * Get the body element
+ *
+ * @return the tbody element
+ */
+ public TestBenchElement getBody() {
+ return getSubPart("#cell");
+ }
+
+ /**
+ * Get the footer element
+ *
+ * @return the tfoot element
+ */
+ public TestBenchElement getFooter() {
+ return getSubPart("#footer");
+ }
+
+ /**
+ * Get the element wrapping the table element
+ *
+ * @return The element that wraps the table element
+ */
+ public TestBenchElement getTableWrapper() {
+ List<WebElement> rootElements = findElements(By.xpath("./div"));
+ return (TestBenchElement) rootElements.get(2);
+ }
+
+ public GridEditorElement getEditor() {
+ return getSubPart("#editor").wrap(GridEditorElement.class)
+ .setGrid(this);
+ }
+
+ /**
+ * Helper function to get Grid subparts wrapped correctly
+ *
+ * @param subPartSelector
+ * SubPart to be used in ComponentLocator
+ * @return SubPart element wrapped in TestBenchElement class
+ */
+ private TestBenchElement getSubPart(String subPartSelector) {
+ return (TestBenchElement) findElement(By.vaadin(subPartSelector));
+ }
+
+ /**
+ * Gets the element that contains the details of a row.
+ *
+ * @since
+ * @param rowIndex
+ * the index of the row for the details
+ * @return the element that contains the details of a row. <code>null</code>
+ * if no widget is defined for the details row
+ * @throws NoSuchElementException
+ * if the given details row is currently not open
+ */
+ public TestBenchElement getDetails(int rowIndex)
+ throws NoSuchElementException {
+ return getSubPart("#details[" + rowIndex + "]");
+ }
+
+ /**
+ * Gets the total number of data rows in the grid.
+ *
+ * @return the number of data rows in the grid,
+ */
+ public long getRowCount() {
+ Long res = (Long) getCommandExecutor()
+ .executeScript("return arguments[0].getBodyRowCount()", this);
+ if (res == null) {
+ throw new IllegalStateException("getBodyRowCount returned null");
+ }
+
+ return res.longValue();
+ }
+
+ /**
+ * Gets all the data rows in the grid.
+ * <p>
+ * Returns an iterable which will lazily scroll rows into views and lazy
+ * load data as needed.
+ *
+ * @return an iterable of all the data rows in the grid.
+ */
+ public Iterable<GridRowElement> getRows() {
+ return new Iterable<GridElement.GridRowElement>() {
+ public Iterator<GridRowElement> iterator() {
+ return new Iterator<GridElement.GridRowElement>() {
+ int nextIndex = 0;
+
+ public GridRowElement next() {
+ return getRow(nextIndex++);
+ }
+
+ public boolean hasNext() {
+ try {
+ getRow(nextIndex);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException(
+ "remove not supported");
+ }
+
+ };
+ }
+ };
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/GridLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/GridLayoutElement.java
new file mode 100644
index 0000000000..31ebca721d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/GridLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.GridLayout")
+public class GridLayoutElement extends AbstractLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalLayoutElement.java
new file mode 100644
index 0000000000..ab03ef7ade
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.HorizontalLayout")
+public class HorizontalLayoutElement extends AbstractOrderedLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalSplitPanelElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalSplitPanelElement.java
new file mode 100644
index 0000000000..db8922e622
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/HorizontalSplitPanelElement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.HorizontalSplitPanel")
+public class HorizontalSplitPanelElement extends AbstractSplitPanelElement {
+
+ private static By bySplit = By.className("v-splitpanel-hsplitter");
+
+ public TestBenchElement getSplitter() {
+ return wrapElement(findElement(bySplit), getCommandExecutor());
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ImageElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ImageElement.java
new file mode 100644
index 0000000000..18a8244595
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ImageElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Image")
+public class ImageElement extends AbstractEmbeddedElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/InlineDateFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/InlineDateFieldElement.java
new file mode 100644
index 0000000000..1cb88a1865
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/InlineDateFieldElement.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.InlineDateField")
+public class InlineDateFieldElement extends DateFieldElement {
+
+ /**
+ * Operation is not supported
+ *
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public String getValue() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Operation is not supported
+ *
+ * @throws UnsupportedOperationException
+ */
+ @Override
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/LabelElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/LabelElement.java
new file mode 100644
index 0000000000..da891ecc84
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/LabelElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Label")
+public class LabelElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/LegacyWindowElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/LegacyWindowElement.java
new file mode 100644
index 0000000000..28c81467e2
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/LegacyWindowElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.LegacyWindow")
+public class LegacyWindowElement extends UIElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/LinkElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/LinkElement.java
new file mode 100644
index 0000000000..da87eb0abc
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/LinkElement.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Link")
+public class LinkElement extends AbstractComponentElement {
+
+ @Override
+ public void click() {
+ getAnchor().click();
+ }
+
+ private WebElement getAnchor() {
+ return findElement(By.tagName("a"));
+ }
+
+ @Override
+ public String getCaption() {
+ return getAnchor().getText();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ListSelectElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ListSelectElement.java
new file mode 100644
index 0000000000..4ce4c9008f
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ListSelectElement.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.Select;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ListSelect")
+public class ListSelectElement extends AbstractSelectElement {
+
+ private Select select;
+ private static By bySelect = By.tagName("select");
+ private WebElement selectElement;
+
+ @Override
+ protected void init() {
+ super.init();
+ selectElement = findElement(bySelect);
+ select = new Select(selectElement);
+ }
+
+ /**
+ * Selects the option(s) with the given text.
+ * <p>
+ * For a ListSelect in multi select mode, adds the given option(s) to the
+ * current selection.
+ *
+ * @param text
+ * the text of the option
+ */
+ public void selectByText(String text) {
+ select.selectByVisibleText(text);
+ if (isPhantomJS() && select.isMultiple()) {
+ // Phantom JS does not fire a change event when
+ // selecting/deselecting items in a multi select
+ fireChangeEvent(selectElement);
+ }
+ }
+
+ /**
+ * Deselects the option(s) with the given text.
+ *
+ * @param text
+ * the text of the option
+ */
+ public void deselectByText(String text) {
+ select.deselectByVisibleText(text);
+ if (isPhantomJS() && select.isMultiple()) {
+ // Phantom JS does not fire a change event when
+ // selecting/deselecting items in a multi select
+ fireChangeEvent(selectElement);
+ }
+ }
+
+ /**
+ * Gets a list of the texts shown for all options.
+ *
+ * @return a list of option texts
+ */
+ public List<String> getOptions() {
+ List<String> options = new ArrayList<String>();
+ for (WebElement webElement : select.getOptions()) {
+ options.add(webElement.getText());
+ }
+ return options;
+ }
+
+ /**
+ * Clear operation is not supported for List Select. This operation has no
+ * effect on List Select element.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+
+ /**
+ * Return value of the list select element
+ *
+ * @return value of the list select element
+ */
+ public String getValue() {
+ return select.getFirstSelectedOption().getText();
+ }
+
+ private void fireChangeEvent(WebElement target) {
+ if (!(getDriver() instanceof JavascriptExecutor)) {
+ return;
+ }
+
+ ((JavascriptExecutor) getDriver()).executeScript(
+ "var ev = document.createEvent('HTMLEvents');" //
+ + "ev.initEvent('change', false, true);" //
+ + "arguments[0].dispatchEvent(ev);", //
+ target);
+
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/MenuBarElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/MenuBarElement.java
new file mode 100644
index 0000000000..18b4240578
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/MenuBarElement.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.MenuBar")
+public class MenuBarElement extends AbstractComponentElement {
+
+ private Point lastItemLocationMovedTo = null;
+
+ /**
+ * Clicks on a visible item.<br>
+ * If the item is a top level menu, the submenu is opened if it was closed,
+ * or closed if it was opened.<br>
+ * If the item is another submenu, that submenu is opened.<br>
+ * If the item is not a submenu, it will be clicked and trigger any actions
+ * associated to it.
+ *
+ * @param item
+ * name of the item to click
+ * @throws NullPointerException
+ * if item does not exist or is not visible
+ */
+ private void clickItem(String item) {
+ WebElement webElement = getVisibleItem("#" + item);
+ if (webElement == null) {
+ throw new NoSuchElementException(
+ "Menu item " + item + " is not available.");
+ }
+ activateOrOpenSubmenu(webElement, true);
+ }
+
+ /**
+ * Clicks the item specified by a full path given as variable arguments.<br>
+ * Fails if path given is not full (ie: last submenu is already opened, and
+ * path given is last item only).
+ * <p>
+ * Example:
+ * </p>
+ *
+ * <pre>
+ * // clicks on &quot;File&quot; item
+ * menuBarElement.click(&quot;File&quot;);
+ * // clicks on &quot;Copy&quot; item in &quot;File&quot; top level menu.
+ * menuBarElement.click(&quot;File&quot;, &quot;Copy&quot;);
+ * </pre>
+ *
+ * @param path
+ * Array of items to click through
+ */
+ public void clickItem(String... path) {
+ if (path.length > 1) {
+ closeAll();
+ }
+ for (String itemName : path) {
+ clickItem(itemName);
+ }
+ }
+
+ /**
+ * Closes all submenus, if any is open.<br>
+ * This is done by clicking on the currently selected top level item.
+ */
+ private void closeAll() {
+ lastItemLocationMovedTo = null;
+ WebElement selectedItem = getSelectedTopLevelItem();
+ if (selectedItem != null) {
+ activateOrOpenSubmenu(selectedItem, true);
+ }
+ }
+
+ private WebElement getSelectedTopLevelItem() {
+ List<WebElement> selectedItems = findElements(
+ By.className("v-menubar-menuitem-selected"));
+ if (selectedItems.size() == 0) {
+ return null;
+ }
+ return selectedItems.get(0);
+ }
+
+ private WebElement getVisibleItem(String item) {
+ return findElement(com.vaadin.testbench.By.vaadin(item));
+ }
+
+ private void activateOrOpenSubmenu(WebElement item, boolean alwaysClick) {
+
+ if (lastItemLocationMovedTo == null || !isAnySubmenuVisible()) {
+ item.click();
+ if (hasSubmenu(item)) {
+ lastItemLocationMovedTo = item.getLocation();
+ }
+ return;
+ }
+
+ // Assumes mouse is still at position of last clicked element
+ Actions action = new Actions(getDriver());
+ action.moveToElement(item);
+ action.build().perform();
+
+ if (isLeaf(item) || isSelectedTopLevelItem(item)) {
+ lastItemLocationMovedTo = null;
+ } else {
+ lastItemLocationMovedTo = item.getLocation();
+ }
+
+ if (alwaysClick || isLeaf(item) || !isAnySubmenuVisible()) {
+ action = new Actions(getDriver());
+ action.click();
+ action.build().perform();
+ }
+ }
+
+ private boolean isSelectedTopLevelItem(WebElement item) {
+ WebElement selectedItem = getSelectedTopLevelItem();
+ if (selectedItem == null) {
+ return false;
+ }
+
+ String itemCaption = item
+ .findElements(By.className("v-menubar-menuitem-caption")).get(0)
+ .getAttribute("innerHTML");
+ String selectedItemCaption = selectedItem
+ .findElements(By.className("v-menubar-menuitem-caption")).get(0)
+ .getAttribute("innerHTML");
+ return itemCaption.equals(selectedItemCaption);
+ }
+
+ private boolean isAnySubmenuVisible() {
+ WebElement selectedItem = getSelectedTopLevelItem();
+ if (selectedItem == null) {
+ return false;
+ }
+ return hasSubmenu(selectedItem);
+ }
+
+ private boolean hasSubmenu(WebElement item) {
+ List<WebElement> submenuIndicatorElements = item
+ .findElements(By.className("v-menubar-submenu-indicator"));
+ return submenuIndicatorElements.size() != 0;
+ }
+
+ private boolean isLeaf(WebElement item) {
+ return !hasSubmenu(item);
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/NativeButtonElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/NativeButtonElement.java
new file mode 100644
index 0000000000..7bbfb67a42
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/NativeButtonElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.NativeButton")
+public class NativeButtonElement extends ButtonElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/NativeSelectElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/NativeSelectElement.java
new file mode 100644
index 0000000000..99becf125e
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/NativeSelectElement.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.support.ui.Select;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.NativeSelect")
+public class NativeSelectElement extends AbstractSelectElement {
+ private Select selectElement;
+
+ @Override
+ protected void init() {
+ super.init();
+ selectElement = new Select(findElement(By.tagName("select")));
+ }
+
+ public List<TestBenchElement> getOptions() {
+ return wrapElements(selectElement.getOptions(), getCommandExecutor());
+ }
+
+ public void selectByText(String text) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ selectElement.selectByVisibleText(text);
+ waitForVaadin();
+ }
+
+ /**
+ * Clear operation is not supported for Native Select. This operation has no
+ * effect on Native Select element.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+
+ /**
+ * Return value of the selected item in the native select element
+ *
+ * @return value of the selected item in the native select element
+ */
+ public String getValue() {
+ return selectElement.getFirstSelectedOption().getText();
+ }
+
+ /**
+ * Select item of the native select element with the specified value
+ *
+ * @param chars
+ * value of the native select item will be selected
+ */
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ selectByText((String) chars);
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/NotificationElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/NotificationElement.java
new file mode 100644
index 0000000000..bc97194fda
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/NotificationElement.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.TimeoutException;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import com.vaadin.testbench.elementsbase.AbstractElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Notification")
+public class NotificationElement extends AbstractElement {
+ /**
+ * Closes a notification
+ *
+ * @throws TimeoutException
+ * If a notification can not be closed and the timeout expires.
+ */
+ public void close() {
+ click();
+ WebDriverWait wait = new WebDriverWait(getDriver(), 10);
+ wait.until(ExpectedConditions
+ .not(ExpectedConditions.presenceOfAllElementsLocatedBy(
+ By.className("v-Notification"))));
+
+ }
+
+ /**
+ * Returns the caption of the Notification element
+ *
+ * @since
+ * @return the caption of the Notification element
+ */
+ public String getCaption() {
+ WebElement popup = findElement(By.className("popupContent"));
+ WebElement caption = popup.findElement(By.tagName("h1"));
+ return caption.getText();
+ }
+
+ /**
+ * Returns description of the Notification element
+ *
+ * @return description of the Notification element
+ */
+ public String getDescription() {
+ WebElement popup = findElement(By.className("popupContent"));
+ WebElement caption = popup.findElement(By.tagName("p"));
+ return caption.getText();
+ }
+
+ /**
+ * Returns type of the Notification element
+ *
+ * @return type of the Notification element
+ */
+ public String getType() {
+ // The info about notification type can be taken only from css rule of
+ // the notification
+ // To get type we search for css rules which represent notification type
+ // This map maps css style rule to type of a notification
+ HashMap<String, String> styleToTypeMap = initStyleToTypeMap();
+ for (Map.Entry<String, String> entry : styleToTypeMap.entrySet()) {
+ String notifType = entry.getKey();
+ // Check notification has css style which describes notification
+ // type
+ if (getAttribute("class").contains(notifType)) {
+ return entry.getValue();
+ }
+ }
+ return "";
+ }
+
+ private HashMap<String, String> initStyleToTypeMap() {
+ HashMap<String, String> styleToType = new HashMap<String, String>();
+ styleToType.put("v-Notification-error", "error");
+ styleToType.put("v-Notification-warning", "warning");
+ styleToType.put("v-Notification-humanized", "humanized");
+ styleToType.put("v-Notification-tray", "tray_notification");
+ return styleToType;
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/OptionGroupElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/OptionGroupElement.java
new file mode 100644
index 0000000000..8c5dcea181
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/OptionGroupElement.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.OptionGroup")
+@Deprecated
+public class OptionGroupElement extends AbstractSelectElement {
+
+ private static org.openqa.selenium.By bySelectOption = By
+ .className("v-select-option");
+ private static org.openqa.selenium.By byLabel = By.tagName("label");
+ private static org.openqa.selenium.By byRadioInput = By.tagName("input");
+
+ public List<String> getOptions() {
+ List<String> optionTexts = new ArrayList<String>();
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ optionTexts.add(option.findElement(byLabel).getText());
+ }
+ return optionTexts;
+ }
+
+ public void selectByText(String text) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ if (text.equals(option.findElement(byLabel).getText())) {
+ WebElement input = option.findElement(byRadioInput);
+ ((TestBenchElement) (input)).clickHiddenElement();
+ }
+ }
+ }
+
+ /**
+ * Return value of the selected option in the option group
+ *
+ * @return value of the selected option in the option group
+ */
+ public String getValue() {
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ WebElement checkedItem;
+ checkedItem = option.findElement(By.tagName("input"));
+ String checked = checkedItem.getAttribute("checked");
+ if (checked != null
+ && checkedItem.getAttribute("checked").equals("true")) {
+ return option.findElement(By.tagName("label")).getText();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Select option in the option group with the specified value
+ *
+ * @param chars
+ * value of the option in the option group which will be selected
+ */
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ selectByText((String) chars);
+ }
+
+ /**
+ * Clear operation is not supported for Option Group. This operation has no
+ * effect on Option Group element.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/PanelElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/PanelElement.java
new file mode 100644
index 0000000000..9f340bf428
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/PanelElement.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Panel")
+public class PanelElement extends AbstractSingleComponentContainerElement {
+ @Override
+ public void scroll(int scrollTop) {
+ ((TestBenchElement) findElement(By.className("v-scrollable")))
+ .scroll(scrollTop);
+ }
+
+ @Override
+ public void scrollLeft(int scrollLeft) {
+ ((TestBenchElement) findElement(By.className("v-scrollable")))
+ .scrollLeft(scrollLeft);
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/PasswordFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/PasswordFieldElement.java
new file mode 100644
index 0000000000..3866aa797e
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/PasswordFieldElement.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.PasswordField")
+public class PasswordFieldElement extends AbstractTextFieldElement {
+ /**
+ * Return value of the password element
+ *
+ * @since
+ * @return value of the password element
+ */
+ @Override
+ public String getValue() {
+ return getAttribute("value");
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/PopupDateFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/PopupDateFieldElement.java
new file mode 100644
index 0000000000..3b9d65f416
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/PopupDateFieldElement.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.PopupDateField")
+@Deprecated
+public class PopupDateFieldElement extends DateFieldElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/PopupViewElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/PopupViewElement.java
new file mode 100644
index 0000000000..7c5bd5512d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/PopupViewElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.PopupView")
+public class PopupViewElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressBarElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressBarElement.java
new file mode 100644
index 0000000000..f567dbf904
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressBarElement.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ProgressBar")
+public class ProgressBarElement extends AbstractFieldElement {
+
+ /**
+ * Retrns the value of the progress bar
+ *
+ * @return
+ */
+ public double getValue() {
+ WebElement indicator = findElement(
+ By.className("v-progressbar-indicator"));
+ String width = getStyleAttribute(indicator, "width");
+ if (!width.endsWith("%")) {
+ return 0;
+ }
+
+ return Double.parseDouble(width.replace("%", "")) / 100.0;
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressIndicatorElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressIndicatorElement.java
new file mode 100644
index 0000000000..6d3d476d3a
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/ProgressIndicatorElement.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ProgressIndicator")
+@Deprecated
+public class ProgressIndicatorElement extends ProgressBarElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/RadioButtonGroupElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/RadioButtonGroupElement.java
new file mode 100644
index 0000000000..4feeaae6ff
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/RadioButtonGroupElement.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.RadioButtonGroup")
+public class RadioButtonGroupElement extends AbstractSelectElement {
+
+ private static org.openqa.selenium.By bySelectOption = By
+ .className("v-select-option");
+ private static org.openqa.selenium.By byLabel = By.tagName("label");
+ private static org.openqa.selenium.By byRadioInput = By.tagName("input");
+
+ public List<String> getOptions() {
+ List<String> optionTexts = new ArrayList<String>();
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ optionTexts.add(option.findElement(byLabel).getText());
+ }
+ return optionTexts;
+ }
+
+ public void selectByText(String text) throws ReadOnlyException {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ if (text.equals(option.findElement(byLabel).getText())) {
+ WebElement input = option.findElement(byRadioInput);
+ ((TestBenchElement) (input)).clickHiddenElement();
+ }
+ }
+ }
+
+ /**
+ * Return value of the selected option in the option group
+ *
+ * @return value of the selected option in the option group
+ */
+ public String getValue() {
+ List<WebElement> options = findElements(bySelectOption);
+ for (WebElement option : options) {
+ WebElement checkedItem;
+ checkedItem = option.findElement(By.tagName("input"));
+ String checked = checkedItem.getAttribute("checked");
+ if (checked != null
+ && checkedItem.getAttribute("checked").equals("true")) {
+ return option.findElement(By.tagName("label")).getText();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Select option in the option group with the specified value
+ *
+ * @param chars
+ * value of the option in the option group which will be selected
+ */
+ public void setValue(CharSequence chars) throws ReadOnlyException {
+ selectByText((String) chars);
+ }
+
+ /**
+ * Clear operation is not supported for Option Group. This operation has no
+ * effect on Option Group element.
+ */
+ @Override
+ public void clear() {
+ super.clear();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/RichTextAreaElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/RichTextAreaElement.java
new file mode 100644
index 0000000000..d5cc9e9a8a
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/RichTextAreaElement.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.RichTextArea")
+public class RichTextAreaElement extends AbstractFieldElement {
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/SelectElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/SelectElement.java
new file mode 100644
index 0000000000..c3b74bddd2
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/SelectElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Select")
+@Deprecated
+public class SelectElement extends ComboBoxElement {
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/SliderElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/SliderElement.java
new file mode 100644
index 0000000000..396a2435b3
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/SliderElement.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.remote.BrowserType;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Slider")
+public class SliderElement extends AbstractFieldElement {
+ /**
+ * Get value of the slider
+ *
+ * Warning! This method cause slider popup to appear on the screen. To hide
+ * this popup just focus any other element on the page.
+ */
+ public String getValue() {
+ List<WebElement> popupElems = findElements(By.vaadin("#popup"));
+ // SubPartAware was implemented after 7.2.6, not sure in which release
+ // it will be included
+ if (popupElems.isEmpty()) {
+ throw new UnsupportedOperationException(
+ "Current version of vaadin doesn't support geting values from sliderElement");
+
+ }
+ WebElement popupElem = popupElems.get(0);
+
+ if (BrowserType.IE.equals(getCapabilities().getBrowserName())
+ && "8".equals(getCapabilities().getVersion())) {
+ return popupElem.getAttribute("innerText");
+ } else {
+ return popupElem.getAttribute("textContent");
+ }
+
+ }
+
+ public WebElement getHandle() {
+ return findElement(By.className("v-slider-handle"));
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TabSheetElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TabSheetElement.java
new file mode 100644
index 0000000000..54c7291d51
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TabSheetElement.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.NoSuchElementException;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBench;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.AbstractElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.TabSheet")
+public class TabSheetElement extends AbstractComponentContainerElement {
+
+ // a locator that does not lead to selecting tabs from a contained inner
+ // TabSheet (#13735)
+ protected org.openqa.selenium.By byTabCell = By
+ .xpath("./div/table/tbody/tr/td[contains(normalize-space(concat(' ', @class, ' ')),"
+ + "normalize-space(' v-tabsheet-tabitem '))]");
+ private static org.openqa.selenium.By byCaption = By
+ .className("v-captiontext");
+ private static org.openqa.selenium.By byClosable = By
+ .className("v-tabsheet-caption-close");
+
+ /**
+ * Gets a list of Tabs inside the Tab container.
+ *
+ * @return List of tabs
+ */
+ public List<String> getTabCaptions() {
+ List<String> tabCaptions = new ArrayList<String>();
+ for (WebElement tab : findElements(byTabCell)) {
+ tabCaptions.add(getTabCaption(tab));
+ }
+ return tabCaptions;
+ }
+
+ /**
+ * Gets the number of tabs contained in this tab sheet.
+ *
+ * @return Number of tabs.
+ */
+ public int getTabCount() {
+ return findElements(byTabCell).size();
+ }
+
+ /**
+ * Opens the tab with the given index.
+ *
+ * @param index
+ * The zero-based index of the tab to be opened.
+ */
+ public void openTab(int index) {
+ List<WebElement> tabs = findElements(byTabCell);
+ if (index < 0 || index >= tabs.size()) {
+ throw new NoSuchElementException(
+ "The tab sheet does not contain a tab with index " + index
+ + ".");
+ }
+ openTab(tabs.get(index));
+ }
+
+ /**
+ * Opens a Tab that has caption equal to given tabCaption.
+ *
+ * @param tabCaption
+ * Caption of the tab to be opened
+ */
+ public void openTab(String tabCaption) {
+ for (WebElement tabCell : findElements(byTabCell)) {
+ String currentCaption = getTabCaption(tabCell);
+ boolean captionMatches = (currentCaption != null
+ && currentCaption.equals(tabCaption))
+ || (currentCaption == null && tabCaption == null);
+ if (captionMatches) {
+ openTab(tabCell);
+ return;
+ }
+ }
+ throw new NoSuchElementException(
+ "Tab with caption " + tabCaption + " was not found.");
+ }
+
+ /**
+ * Opens the given tab by clicking its caption text or icon. If the tab has
+ * neither text caption nor icon, clicks at a fixed position.
+ *
+ * @param tabCell
+ * The tab to be opened.
+ */
+ private void openTab(WebElement tabCell) {
+ // Open the tab by clicking its caption text if it exists.
+ List<WebElement> tabCaptions = tabCell.findElements(byCaption);
+ if (tabCaptions.size() > 0) {
+ tabCaptions.get(0).click();
+ return;
+ }
+ // If no caption text was found, click the icon of the tab.
+ List<WebElement> tabIcons = tabCell
+ .findElements(By.className("v-icon"));
+ if (tabIcons.size() > 0) {
+ tabIcons.get(0).click();
+ return;
+ }
+ // If neither text nor icon caption was found, click at a position that
+ // is unlikely to close the tab.
+ ((TestBenchElement) tabCell).click(10, 10);
+ }
+
+ /**
+ * If the tab with given index is closable, closes it.
+ *
+ * @param index
+ * The index of the tab to be closed
+ */
+ public void closeTab(int index) {
+ List<WebElement> tabs = findElements(byTabCell);
+ if (index < 0 || index >= tabs.size()) {
+ throw new NoSuchElementException(
+ "The tab sheet does not contain a tab with index " + index
+ + ".");
+ }
+ WebElement tabCell = tabs.get(index);
+ closeTab(tabCell);
+ }
+
+ /**
+ * If tab with given caption is closable, closes it.
+ *
+ * @param tabCaption
+ * Caption of the tab to be closed
+ */
+ public void closeTab(String tabCaption) {
+ for (WebElement tabCell : findElements(byTabCell)) {
+ String currentCaption = getTabCaption(tabCell);
+ boolean captionMatches = (currentCaption != null
+ && currentCaption.equals(tabCaption))
+ || (currentCaption == null && tabCaption == null);
+ if (captionMatches) {
+ closeTab(tabCell);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Closes the given tab if it is closable.
+ *
+ * @param tabCell
+ * The tab to be closed
+ */
+ private void closeTab(WebElement tabCell) {
+ try {
+ tabCell.findElement(byClosable).click();
+ // Going further causes a StaleElementReferenceException.
+ return;
+ } catch (NoSuchElementException e) {
+ // Do nothing.
+ }
+ }
+
+ /**
+ * Gets TabSheet content and wraps it in given class.
+ *
+ * @param clazz
+ * Components element class
+ * @return TabSheet content wrapped in given class
+ */
+ public <T extends AbstractElement> T getContent(Class<T> clazz) {
+ return TestBench.createElement(clazz,
+ $$(AbstractComponentElement.class).first().getWrappedElement(),
+ getCommandExecutor());
+ }
+
+ /**
+ * Returns the caption text of the given tab. If the tab has no caption,
+ * returns null.
+ *
+ * @param tabCell
+ * A web element representing a tab, as given by
+ * findElements(byTabCell).get(index).
+ * @return The caption of tabCell or null if tabCell has no caption.
+ */
+ private String getTabCaption(WebElement tabCell) {
+ List<WebElement> captionElements = tabCell.findElements(byCaption);
+ if (captionElements.size() == 0) {
+ return null;
+ } else {
+ return captionElements.get(0).getText();
+ }
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TableElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TableElement.java
new file mode 100644
index 0000000000..68a42533b1
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TableElement.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.JavascriptExecutor;
+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.TestBenchElement;
+import com.vaadin.testbench.elementsbase.AbstractElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Table")
+@Deprecated
+public class TableElement extends AbstractSelectElement {
+
+ /**
+ * Function to find a Table cell. Looking for a cell that is currently not
+ * visible will throw NoSuchElementException
+ *
+ * @param row
+ * 0 based row index
+ * @param column
+ * 0 based column index
+ * @return TestBenchElement containing wanted cell.
+ * @throws NoSuchElementException
+ * if the cell (row, column) is not found.
+ */
+ public TestBenchElement getCell(int row, int column) {
+
+ TestBenchElement cell = wrapElement(
+ findElement(By.vaadin("#row[" + row + "]/col[" + column + "]")),
+ getCommandExecutor());
+
+ return cell;
+ }
+
+ /**
+ * Return table row element by zero-based index
+ *
+ * @return table row element by zero-based index
+ */
+ public TableRowElement getRow(int row) {
+ TestBenchElement rowElem = wrapElement(
+ findElement(By.vaadin("#row[" + row + "]")),
+ getCommandExecutor());
+ return rowElem.wrap(TableRowElement.class);
+ }
+
+ /**
+ * Returns the header cell with the given column index.
+ *
+ * @param column
+ * 0 based column index
+ * @return TableHeaderElement containing the wanted header cell
+ */
+ public TableHeaderElement getHeaderCell(int column) {
+ TestBenchElement headerCell = wrapElement(
+ findElement(By.vaadin("#header[" + column + "]")),
+ getCommandExecutor());
+ return headerCell.wrap(TableHeaderElement.class);
+ }
+
+ /**
+ * Function to get footer cell with given column index
+ *
+ * @param column
+ * 0 based column index
+ * @return TestBenchElement containing wanted footer cell
+ */
+ public TestBenchElement getFooterCell(int column) {
+ TestBenchElement footerCell = wrapElement(
+ findElement(By.vaadin("#footer[" + column + "]")),
+ getCommandExecutor());
+ return footerCell;
+ }
+
+ @Override
+ public void scroll(int scrollTop) {
+ ((TestBenchElement) findElement(By.className("v-scrollable")))
+ .scroll(scrollTop);
+ }
+
+ @Override
+ public void scrollLeft(int scrollLeft) {
+ ((TestBenchElement) findElement(By.className("v-scrollable")))
+ .scrollLeft(scrollLeft);
+ }
+
+ @Override
+ public void contextClick() {
+ WebElement tbody = findElement(By.className("v-table-body"));
+ // There is a problem in with phantomjs driver, just calling
+ // contextClick() doesn't work. We have to use javascript.
+ if (isPhantomJS()) {
+ JavascriptExecutor js = getCommandExecutor();
+ String scr = "var element=arguments[0];"
+ + "var ev = document.createEvent('HTMLEvents');"
+ + "ev.initEvent('contextmenu', true, false);"
+ + "element.dispatchEvent(ev);";
+ js.executeScript(scr, tbody);
+ } else {
+ new Actions(getDriver()).contextClick(tbody).build().perform();
+ }
+ }
+
+ public static class ContextMenuElement extends AbstractElement {
+
+ public WebElement getItem(int index) {
+ return findElement(
+ By.xpath(".//table//tr[" + (index + 1) + "]//td/*"));
+ }
+
+ }
+
+ /**
+ * Fetches the context menu for the table
+ *
+ * @return {@link com.vaadin.testbench.elements.TableElement.ContextMenuElement}
+ * @throws java.util.NoSuchElementException
+ * if the menu isn't open
+ */
+ public ContextMenuElement getContextMenu() {
+ try {
+ WebElement cm = getDriver()
+ .findElement(By.className("v-contextmenu"));
+ return wrapElement(cm, getCommandExecutor())
+ .wrap(ContextMenuElement.class);
+ } catch (WebDriverException e) {
+ throw new NoSuchElementException("Context menu not found", e);
+ }
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TableHeaderElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TableHeaderElement.java
new file mode 100644
index 0000000000..5715d3fcfa
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TableHeaderElement.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+@Deprecated
+public class TableHeaderElement extends AbstractComponentElement {
+
+ @Override
+ public String getCaption() {
+ WebElement captionElement = findElement(
+ By.className("v-table-caption-container"));
+ return captionElement.getText();
+ }
+
+ /**
+ * Returns column resize handle.
+ *
+ * You can resize column by using selenium Actions i.e. new
+ * Actions(getDriver()).clickAndHold(handle).moveByOffset(x,
+ * y).release().build().perform();
+ *
+ * @return column resize handle
+ */
+ public WebElement getResizeHandle() {
+ return findElement(By.className("v-table-resizer"));
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TableRowElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TableRowElement.java
new file mode 100644
index 0000000000..25a656599d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TableRowElement.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.exceptions.NoSuchColumnException;
+
+@Deprecated
+public class TableRowElement extends AbstractComponentElement {
+
+ /**
+ * Returns cell from current row by index. Returns the same element as
+ * $(TableElement.class).first().getCell(row, col).
+ *
+ * @see com.vaadin.testbench.elements.TableElement#getCell(int, int)
+ * @param col
+ * column index
+ * @return cell from current row by index.
+ */
+ public TestBenchElement getCell(int col) {
+ List<WebElement> cells = getWrappedElement()
+ .findElements(By.tagName("td"));
+ if (col >= cells.size()) {
+ throw new NoSuchColumnException();
+ }
+
+ WebElement cellContent = cells.get(col);
+ return wrapElement(cellContent.findElement(By.xpath("./*")),
+ getCommandExecutor());
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TextAreaElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TextAreaElement.java
new file mode 100644
index 0000000000..e5e5ee90f4
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TextAreaElement.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.Keys;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.TextArea")
+public class TextAreaElement extends AbstractTextFieldElement {
+ /**
+ * Return value of the field element
+ *
+ * @since
+ * @return value of the field element
+ */
+ @Override
+ public String getValue() {
+ return getAttribute("value");
+ }
+
+ @Override
+ public void setValue(CharSequence chars) {
+ if (isReadOnly()) {
+ throw new ReadOnlyException();
+ }
+ // clears without triggering an event
+ clearElementClientSide(this);
+ focus();
+ sendKeys(chars);
+ sendKeys(Keys.TAB);
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TextFieldElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TextFieldElement.java
new file mode 100644
index 0000000000..aab5d474aa
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TextFieldElement.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.TextField")
+public class TextFieldElement extends AbstractTextFieldElement {
+ public String getValue() {
+ return getAttribute("value");
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeElement.java
new file mode 100644
index 0000000000..d879749c24
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeElement.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Tree")
+@Deprecated
+public class TreeElement extends AbstractSelectElement {
+ /**
+ * Returns selected item of the tree. In multiselect mode returns first
+ * selected item. If there is no selected item returns empty string
+ *
+ * @return selected item of the tree
+ */
+ public String getValue() {
+ List<WebElement> selectedElements = findElements(
+ By.className("v-tree-node-selected"));
+ if (selectedElements.isEmpty()) {
+ return "";
+ } else {
+ return selectedElements.get(0).getText();
+ }
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableElement.java
new file mode 100644
index 0000000000..2331cbc9f0
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableElement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.TreeTable")
+@Deprecated
+public class TreeTableElement extends TableElement {
+
+ @Override
+ public TreeTableRowElement getRow(int row) {
+ TestBenchElement element = super.getRow(row);
+ return element.wrap(TreeTableRowElement.class);
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableRowElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableRowElement.java
new file mode 100644
index 0000000000..be6bf144a3
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TreeTableRowElement.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.List;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+@Deprecated
+public class TreeTableRowElement extends TableRowElement {
+
+ /**
+ * Either expand collapsed row or collapse expanded row.
+ */
+ public void toggleExpanded() {
+ List<WebElement> expandButtons = getWrappedElement()
+ .findElements(By.className("v-treetable-treespacer"));
+ if (expandButtons.size() > 0) {
+ expandButtons.get(0).click();
+ }
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/TwinColSelectElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/TwinColSelectElement.java
new file mode 100644
index 0000000000..c68ade8ff4
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/TwinColSelectElement.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.Select;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.TwinColSelect")
+public class TwinColSelectElement extends AbstractSelectElement {
+
+ private Select options;
+ private Select selectedOptions;
+ private WebElement deselButton;
+ private WebElement selButton;
+ private static org.openqa.selenium.By bySelect = By.tagName("select");
+ private static org.openqa.selenium.By byButton = By.className("v-button");
+
+ @Override
+ protected void init() {
+ super.init();
+ List<WebElement> selectElements = findElements(bySelect);
+ options = new Select(selectElements.get(0));
+ selectedOptions = new Select(selectElements.get(1));
+ List<WebElement> buttons = findElements(byButton);
+ selButton = buttons.get(0);
+ deselButton = buttons.get(1);
+ }
+
+ private void deselectAll() {
+ if (selectedOptions.isMultiple()) {
+ if (selectedOptions.getAllSelectedOptions()
+ .size() != selectedOptions.getOptions().size()) {
+ for (int i = 0, l = selectedOptions.getOptions()
+ .size(); i < l; ++i) {
+ selectedOptions.selectByIndex(i);
+ }
+ }
+ deselButton.click();
+ }
+ while (selectedOptions.getOptions().size() > 0) {
+ selectedOptions.selectByIndex(0);
+ deselButton.click();
+ }
+ }
+
+ public void deselectByText(String text) {
+ selectedOptions.deselectAll();
+ selectedOptions.selectByVisibleText(text);
+ deselButton.click();
+ }
+
+ /**
+ * Functionality to find option texts of all currently selected options.
+ *
+ * @return List of visible text for all selected options
+ */
+ public List<String> getValues() {
+ return getOptionsFromSelect(selectedOptions);
+ }
+
+ /**
+ * Functionality to find all option texts.
+ *
+ * @return List of visible text for all options
+ */
+ public List<String> getOptions() {
+ List<String> optionTexts = getOptionsFromSelect(options);
+ optionTexts.addAll(getValues());
+ return optionTexts;
+ }
+
+ /**
+ * Gets the available option texts, i.e. all values which have not been
+ * selected.
+ *
+ * @return List of visible text for available options
+ */
+ public List<String> getAvailableOptions() {
+ return getOptionsFromSelect(options);
+ }
+
+ public void selectByText(String text) {
+ options.deselectAll();
+ options.selectByVisibleText(text);
+ selButton.click();
+ }
+
+ private List<String> getOptionsFromSelect(Select select) {
+ List<String> optionTexts = new ArrayList<String>();
+ for (WebElement option : select.getOptions()) {
+ optionTexts.add(option.getText());
+ }
+ return optionTexts;
+ }
+
+ /**
+ * Return first selected item (item in the right part of component)
+ */
+ public String getValue() {
+ String value = "";
+ WebElement selectedElement = findElement(
+ By.className("v-select-twincol-selections"));
+ List<WebElement> optionElements = selectedElement
+ .findElements(By.tagName("option"));
+ if (!optionElements.isEmpty()) {
+ value = optionElements.get(0).getText();
+ }
+ return value;
+ }
+
+ @Override
+ public void clear() {
+ deselectAll();
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/UIElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/UIElement.java
new file mode 100644
index 0000000000..f942497e6d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/UIElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.UI")
+public class UIElement extends AbstractSingleComponentContainerElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/UploadElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/UploadElement.java
new file mode 100644
index 0000000000..b9f3341196
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/UploadElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Upload")
+public class UploadElement extends AbstractComponentElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalLayoutElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalLayoutElement.java
new file mode 100644
index 0000000000..3c75a91b68
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalLayoutElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.VerticalLayout")
+public class VerticalLayoutElement extends AbstractOrderedLayoutElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalSplitPanelElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalSplitPanelElement.java
new file mode 100644
index 0000000000..a2d72ce50f
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/VerticalSplitPanelElement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+
+import com.vaadin.testbench.TestBenchElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.VerticalSplitPanel")
+public class VerticalSplitPanelElement extends AbstractSplitPanelElement {
+
+ private static By bySplit = By.className("v-splitpanel-vsplitter");
+
+ public TestBenchElement getSplitter() {
+ return wrapElement(findElement(bySplit), getCommandExecutor());
+ }
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/VideoElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/VideoElement.java
new file mode 100644
index 0000000000..0dd32820ea
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/VideoElement.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.Video")
+public class VideoElement extends AbstractMediaElement {
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/elements/WindowElement.java b/testbench-api/src/main/java/com/vaadin/testbench/elements/WindowElement.java
new file mode 100644
index 0000000000..08c1a2f28d
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/elements/WindowElement.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2016 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.testbench.elements;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+/**
+ * Element API for the Window class.
+ *
+ * Note that parts of the Window element API has limitations on IE8 and Phantom.
+ */
+@ServerClass("com.vaadin.ui.Window")
+public class WindowElement extends PanelElement {
+
+ private static final String HEADER_CLASS = "v-window-header";
+ private static final String RESTORE_BOX_CLASS = "v-window-restorebox";
+ private static final String MAXIMIZE_BOX_CLASS = "v-window-maximizebox";
+ private static final String CLOSE_BOX_CLASS = "v-window-closebox";
+
+ /**
+ * Clicks the close button of the window
+ */
+ public void close() {
+ getCloseButton().click();
+ }
+
+ /**
+ * Clicks the restore button of the window
+ */
+ public void restore() {
+ if (isMaximized()) {
+ getRestoreButton().click();
+ } else {
+ throw new IllegalStateException(
+ "Window is not maximized, cannot be restored.");
+ }
+ }
+
+ /**
+ * Check if this window is currently maximized
+ */
+ public boolean isMaximized() {
+ return isElementPresent(By.className(RESTORE_BOX_CLASS));
+ }
+
+ /**
+ * Clicks the maximize button of the window
+ */
+ public void maximize() {
+ if (!isMaximized()) {
+ getMaximizeButton().click();
+ } else {
+ throw new IllegalStateException(
+ "Window is already maximized, cannot maximize.");
+ }
+ }
+
+ private WebElement getRestoreButton() {
+ return findElement(By.className(RESTORE_BOX_CLASS));
+ }
+
+ private WebElement getMaximizeButton() {
+ return findElement(By.className(MAXIMIZE_BOX_CLASS));
+ }
+
+ private WebElement getCloseButton() {
+ return findElement(By.className(CLOSE_BOX_CLASS));
+ }
+
+ /**
+ * @return the caption of the window
+ */
+ @Override
+ public String getCaption() {
+ return findElement(By.className(HEADER_CLASS)).getText();
+ }
+
+}
diff --git a/testbench-api/src/main/java/com/vaadin/testbench/exceptions/NoSuchColumnException.java b/testbench-api/src/main/java/com/vaadin/testbench/exceptions/NoSuchColumnException.java
new file mode 100644
index 0000000000..a9e9cbfba3
--- /dev/null
+++ b/testbench-api/src/main/java/com/vaadin/testbench/exceptions/NoSuchColumnException.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2000-2016 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.testbench.exceptions;
+
+public class NoSuchColumnException extends RuntimeException {
+
+}
diff --git a/uitest-common/pom.xml b/uitest-common/pom.xml
index 2375f8a072..28ae930e24 100644
--- a/uitest-common/pom.xml
+++ b/uitest-common/pom.xml
@@ -49,7 +49,8 @@
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
- <artifactId>vaadin-testbench</artifactId>
+ <artifactId>vaadin-testbench-api</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
diff --git a/uitest/ivy.xml b/uitest/ivy.xml
index 04dc6a1c6a..33ac7c7c04 100644
--- a/uitest/ivy.xml
+++ b/uitest/ivy.xml
@@ -118,8 +118,8 @@
<!-- Mainly for SQLContainer tests -->
<dependency org="org.hsqldb" name="hsqldb" rev="2.2.6"
conf="build -> default" />
- <dependency org="com.vaadin" name="vaadin-testbench"
- rev="5.0.0.alpha2" conf="build-provided -> default" />
+ <dependency org="com.vaadin" name="vaadin-testbench-api"
+ rev="${vaadin.version}" conf="build-provided -> 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 -> default" />