diff options
Diffstat (limited to 'uitest')
137 files changed, 14728 insertions, 58 deletions
diff --git a/uitest/build.xml b/uitest/build.xml index 02b97fb3a0..e6c68a90aa 100644 --- a/uitest/build.xml +++ b/uitest/build.xml @@ -1,6 +1,7 @@ <?xml version="1.0"?> -<project name="vaadin-uitest" basedir="." default="publish-local" xmlns:ivy="antlib:org.apache.ivy.ant"> +<project name="vaadin-uitest" basedir="." default="publish-local" + xmlns:ivy="antlib:org.apache.ivy.ant"> <description> Provides a uitest WAR containing Vaadin UI tests </description> @@ -12,20 +13,24 @@ <property name="uitest.dir" location="${vaadin.basedir}/uitest" /> <property name="result.dir" value="result" /> <property name="theme.result.dir" value="${result.dir}/VAADIN/themes" /> - <property name="result.war" location="${result.dir}/lib/${module.name}-${vaadin.version}.war" /> + <property name="result.war" + location="${result.dir}/lib/${module.name}-${vaadin.version}.war" /> <path id="classpath.compile.custom"> </path> <target name="dependencies"> - <!-- This is copied from common.xml to be able to add server.test.source + <!-- This is copied from common.xml to be able to add server.test.source to the source path --> - <ivy:resolve log="download-only" resolveid="common" conf="build, build-provided" /> - <ivy:cachepath pathid="classpath.compile.dependencies" conf="build, build-provided" /> + <ivy:resolve log="download-only" resolveid="common" + conf="build, build-provided" /> + <ivy:cachepath pathid="classpath.compile.dependencies" + conf="build, build-provided" /> </target> - <target name="compile" description="Compiles the module" depends="dependencies"> + <target name="compile" description="Compiles the module" + depends="dependencies"> <fail unless="module.name" message="No module name given" /> <property name="result.dir" location="result" /> @@ -35,16 +40,21 @@ <mkdir dir="${classes}" /> <!-- TODO: Get rid of this --> - <javac destdir="${classes}" source="${vaadin.java.version}" target="${vaadin.java.version}" debug="true" encoding="UTF-8" includeantruntime="false"> + <javac destdir="${classes}" source="${vaadin.java.version}" + target="${vaadin.java.version}" debug="true" encoding="UTF-8" + includeantruntime="false"> <src path="${server.test.sources}" /> <include name="com/vaadin/tests/data/bean/**" /> <include name="com/vaadin/tests/VaadinClasses.java" /> - <include name="com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java" /> + <include + name="com/vaadin/data/util/sqlcontainer/SQLTestsConstants.java" /> <classpath refid="classpath.compile.dependencies" /> <classpath refid="classpath.compile.custom" /> </javac> - <javac destdir="${classes}" source="${vaadin.java.version}" target="${vaadin.java.version}" debug="true" encoding="UTF-8" includeantruntime="false"> + <javac destdir="${classes}" source="${vaadin.java.version}" + target="${vaadin.java.version}" debug="true" encoding="UTF-8" + includeantruntime="false"> <src path="${src}" /> <classpath location="${classes}" /> <classpath refid="classpath.compile.dependencies" /> @@ -53,7 +63,8 @@ </target> <target name="testing-widgetset" depends="dependencies,compile"> - <property name="module" value="com.vaadin.tests.widgetset.TestingWidgetSet" /> + <property name="module" + value="com.vaadin.tests.widgetset.TestingWidgetSet" /> <property name="style" value="OBF" /> <property name="localWorkers" value="6" /> <property name="extraParams" value="" /> @@ -65,7 +76,8 @@ <echo>Compiling ${module} to ${module.output.dir}</echo> <!-- compile the module --> - <java classname="com.google.gwt.dev.Compiler" classpathref="classpath.compile.dependencies" failonerror="yes" fork="yes" maxmemory="512m"> + <java classname="com.google.gwt.dev.Compiler" classpathref="classpath.compile.dependencies" + failonerror="yes" fork="yes" maxmemory="512m"> <classpath location="src" /> <classpath location="${classes}" /> <arg value="-workDir" /> @@ -92,15 +104,18 @@ </target> - <target name="war" depends="dependencies, compile, compile-test-themes, testing-widgetset"> + <target name="war" + depends="dependencies, compile, compile-test-themes, testing-widgetset"> <property name="result.dir" location="result" /> <property name="classes" location="${result.dir}/classes" /> <property name="WebContent.dir" location="${vaadin.basedir}/WebContent" /> <property name="deps.dir" location="${result.dir}/deps" /> <property name="src" location="${result.dir}/../src" /> - <ivy:resolve log="download-only" resolveid="common" conf="build" /> - <ivy:cachepath pathid="classpath.runtime.dependencies" conf="build" /> + <ivy:resolve log="download-only" resolveid="common" + conf="build" /> + <ivy:cachepath pathid="classpath.runtime.dependencies" + conf="build" /> <delete dir="${deps.dir}" /> <mkdir dir="${deps.dir}" /> @@ -110,16 +125,14 @@ </copy> <delete> - <!-- Avoid including some potentially conflicting jars in the war --> + <!-- Avoid including some potentially conflicting jars in the + war --> <fileset dir="${deps.dir}" includes="jetty-*.jar" /> <fileset dir="${deps.dir}" includes="servlet-api-*.jar" /> </delete> - <!-- Ensure filtered webcontent files are available --> - <antcall target="common.filter.webcontent" /> - <war destfile="${result.war}" duplicate="fail" index="true"> - <fileset refid="common.files.for.all.jars" /> + <fileset dir="${common.jarfiles.dir}" /> <fileset dir="${result.dir}"> <include name="VAADIN/widgetsets/**/*" /> <include name="VAADIN/themes/tests-valo*/**" /> @@ -156,38 +169,45 @@ <target name="test" depends="checkstyle"> </target> - <target name="test-testbench" depends="clean-testbench-errors" description="Run all TestBench based tests, including server tests"> + <target name="test-testbench" depends="clean-testbench-errors" + description="Run all TestBench based tests, including server tests"> <parallel> <daemons> <!-- Start server --> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + inheritall="true" inheritrefs="true" target="deploy-and-start" /> </daemons> <sequential> <!-- Server tests --> - <!-- Sleep before running integration tests so testbench 2 - tests have time to compile and start --> + <!-- Sleep before running integration tests so testbench + 2 tests have time to compile and start --> <sleep minutes="4" /> - <ant antfile="${uitest.dir}/integration_tests.xml" target="integration-test-all" inheritall="false" inheritrefs="false"> + <ant antfile="${uitest.dir}/integration_tests.xml" + target="integration-test-all" inheritall="false" + inheritrefs="false"> <property name="demo.war" value="${war.file}" /> </ant> </sequential> <sequential> <!-- Wait for server to start --> - <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + target="wait-for-startup" /> <!-- Run all different kinds of TestBench tests in parallel --> <parallel> <!-- Legacy TestBench 2 tests --> <sequential> - <ant antfile="${uitest.dir}/test.xml" target="tb2-tests" /> + <ant antfile="${uitest.dir}/test.xml" + target="tb2-tests" /> <echo message="TestBench 2 tests complete" /> </sequential> <!-- TestBench 3 tests --> <sequential> - <ant antfile="${uitest.dir}/tb3test.xml" target="run-all-tb3-tests" inheritall="true" /> + <ant antfile="${uitest.dir}/tb3test.xml" + target="run-all-tb3-tests" inheritall="true" /> <echo message="TestBench 3 tests complete" /> </sequential> </parallel> @@ -196,13 +216,17 @@ </target> <target name="test-server" depends="clean-testbench-errors"> - <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> + <property name="war.file" + location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> <parallel> <daemons> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + inheritall="true" inheritrefs="true" target="deploy-and-start" /> </daemons> <sequential> - <ant antfile="${uitest.dir}/integration_tests.xml" target="integration-test-all" inheritall="false" inheritrefs="false"> + <ant antfile="${uitest.dir}/integration_tests.xml" + target="integration-test-all" inheritall="false" + inheritrefs="false"> <property name="demo.war" value="${war.file}" /> </ant> </sequential> @@ -210,36 +234,45 @@ </target> <target name="test-tb2" depends="clean-testbench-errors"> - <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> + <property name="war.file" + location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> <parallel> <daemons> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + inheritall="true" inheritrefs="true" target="deploy-and-start" /> </daemons> <sequential> - <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + target="wait-for-startup" /> <ant antfile="${uitest.dir}/test.xml" target="tb2-tests" /> </sequential> </parallel> </target> <target name="test-tb3" depends="clean-testbench-errors"> - <property name="war.file" location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> + <property name="war.file" + location="${vaadin.basedir}/result/artifacts/${vaadin.version}/vaadin-uitest/vaadin-uitest-${vaadin.version}.war" /> <parallel> <daemons> - <ant antfile="${uitest.dir}/vaadin-server.xml" inheritall="true" inheritrefs="true" target="deploy-and-start" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + inheritall="true" inheritrefs="true" target="deploy-and-start" /> </daemons> <sequential> - <ant antfile="${uitest.dir}/vaadin-server.xml" target="wait-for-startup" /> - <ant antfile="${uitest.dir}/tb3test.xml" target="run-all-tb3-tests" inheritall="true" /> + <ant antfile="${uitest.dir}/vaadin-server.xml" + target="wait-for-startup" /> + <ant antfile="${uitest.dir}/tb3test.xml" target="run-all-tb3-tests" + inheritall="true" /> </sequential> </parallel> </target> <target name="clean-testbench-errors"> - <fail unless="com.vaadin.testbench.screenshot.directory" message="Define screenshot directory using -Dcom.vaadin.testbench.screenshot.directory" /> + <fail unless="com.vaadin.testbench.screenshot.directory" + message="Define screenshot directory using -Dcom.vaadin.testbench.screenshot.directory" /> <mkdir dir="${com.vaadin.testbench.screenshot.directory}/errors" /> <delete> - <fileset dir="${com.vaadin.testbench.screenshot.directory}/errors"> + <fileset + dir="${com.vaadin.testbench.screenshot.directory}/errors"> <include name="*" /> </fileset> </delete> @@ -268,22 +301,28 @@ <param name="theme" value="tests-valo-blueprint" /> </antcall> <antcall target="compile-theme"> - <param name="theme" value="tests-valo-light" /> + <param name="theme" value="tests-valo-light" /> </antcall> </target> <target name="compile-theme" depends="copy-theme"> - <fail unless="theme" message="You must give the theme name to compile in the 'theme' parameter" /> + <fail unless="theme" + message="You must give the theme name to compile in the 'theme' parameter" /> - <ivy:resolve log="download-only" resolveid="common" conf="compile-theme" /> - <ivy:cachepath pathid="classpath.compile.theme" conf="compile-theme" /> - <ivy:cachepath pathid="classpath.runtime.theme" conf="build" /> + <ivy:resolve log="download-only" resolveid="common" + conf="compile-theme" /> + <ivy:cachepath pathid="classpath.compile.theme" + conf="compile-theme" /> + <ivy:cachepath pathid="classpath.runtime.theme" + conf="build" /> <echo>Compiling ${theme}</echo> <mkdir dir="${theme.result.dir}" /> <!-- compile the theme --> - <java classname="com.vaadin.buildhelpers.CompileTheme" classpathref="classpath.compile.theme" failonerror="yes" fork="yes" maxmemory="512m"> + <java classname="com.vaadin.buildhelpers.CompileTheme" + classpathref="classpath.compile.theme" failonerror="yes" + fork="yes" maxmemory="512m"> <arg value="--theme" /> <arg value="${theme}" /> <arg value="--theme-folder" /> @@ -298,7 +337,8 @@ </target> <target name="copy-theme"> - <fail unless="theme" message="You must give the theme name to copy n the 'theme' parameter" /> + <fail unless="theme" + message="You must give the theme name to copy n the 'theme' parameter" /> <property name="theme.source.dir" location="../WebContent/VAADIN/themes" /> <copy todir="${theme.result.dir}"> diff --git a/uitest/src/com/vaadin/testbench/elements/GridElement.java b/uitest/src/com/vaadin/testbench/elements/GridElement.java new file mode 100644 index 0000000000..0c94c1dd88 --- /dev/null +++ b/uitest/src/com/vaadin/testbench/elements/GridElement.java @@ -0,0 +1,325 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.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.TestBenchElement; + +/** + * 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 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 + * column index + * @return the editor field for given location + */ + public TestBenchElement getField(int colIndex) { + return grid.getSubPart("#editor[" + colIndex + "]"); + } + + /** + * Saves the fields of this editor. + * <p> + * <em>Note:</em> that this closes the editor making this element + * useless. + */ + public void save() { + getField(0); + List<WebElement> buttons = findElements(By.xpath("./button")); + buttons.get(0).click(); + } + + /** + * Cancels this editor. + * <p> + * <em>Note:</em> that this closes the editor making this element + * useless. + */ + public void cancel() { + getField(0); + List<WebElement> buttons = findElements(By.xpath("./button")); + buttons.get(1).click(); + } + } + + /** + * 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 WebElement 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 WebElement getFooterRow(int rowIndex) { + return getSubPart("#footer[" + rowIndex + "]"); + } + + /** + * Get the vertical scroll element + * + * @return The element representing the vertical scrollbar + */ + public WebElement getVerticalScroller() { + List<WebElement> rootElements = findElements(By.xpath("./div")); + return rootElements.get(0); + } + + /** + * Get the horizontal scroll element + * + * @return The element representing the horizontal scrollbar + */ + public WebElement getHorizontalScroller() { + List<WebElement> rootElements = findElements(By.xpath("./div")); + return rootElements.get(1); + } + + /** + * Get the header element + * + * @return The thead element + */ + public WebElement getHeader() { + return getSubPart("#header"); + } + + /** + * Get the body element + * + * @return the tbody element + */ + public WebElement getBody() { + return getSubPart("#cell"); + } + + /** + * Get the footer element + * + * @return the tfoot element + */ + public WebElement getFooter() { + return getSubPart("#footer"); + } + + /** + * Get the element wrapping the table element + * + * @return The element that wraps the table element + */ + public WebElement getTableWrapper() { + List<WebElement> rootElements = findElements(By.xpath("./div")); + return 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)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java b/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java new file mode 100644 index 0000000000..cc5be455cd --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/AbstractGridColumnAutoWidthTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@SuppressWarnings("boxing") +@TestCategory("grid") +public abstract class AbstractGridColumnAutoWidthTest extends MultiBrowserTest { + + public static final int TOTAL_MARGIN_PX = 13; + + @Before + public void before() { + openTestURL(); + } + + @Test + public void testNarrowHeaderWideBody() { + WebElement[] col = getColumn(1); + int headerWidth = col[0].getSize().getWidth(); + int bodyWidth = col[1].getSize().getWidth(); + int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX; + + assertLessThan("header should've been narrower than body", headerWidth, + bodyWidth); + assertEquals("column should've been roughly as wide as the body", + bodyWidth, colWidth, 5); + } + + @Test + public void testWideHeaderNarrowBody() { + WebElement[] col = getColumn(2); + int headerWidth = col[0].getSize().getWidth(); + int bodyWidth = col[1].getSize().getWidth(); + int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX; + + assertGreater("header should've been wider than body", headerWidth, + bodyWidth); + assertEquals("column should've been roughly as wide as the header", + headerWidth, colWidth, 5); + + } + + @Test + public void testTooNarrowColumn() { + if (BrowserUtil.isIE(getDesiredCapabilities())) { + // IE can't deal with overflow nicely. + return; + } + + WebElement[] col = getColumn(3); + int headerWidth = col[0].getSize().getWidth(); + int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX; + + assertLessThan("column should've been narrower than content", colWidth, + headerWidth); + } + + @Test + public void testTooWideColumn() { + WebElement[] col = getColumn(4); + int headerWidth = col[0].getSize().getWidth(); + int colWidth = col[2].getSize().getWidth() - TOTAL_MARGIN_PX; + + assertGreater("column should've been wider than content", colWidth, + headerWidth); + } + + @Test + public void testColumnsRenderCorrectly() throws IOException { + compareScreen("initialRender"); + } + + private WebElement[] getColumn(int i) { + WebElement[] col = new WebElement[3]; + col[0] = getDriver().findElement( + By.xpath("//thead//th[" + (i + 1) + "]/span")); + col[1] = getDriver().findElement( + By.xpath("//tbody//td[" + (i + 1) + "]/span")); + col[2] = getDriver().findElement( + By.xpath("//tbody//td[" + (i + 1) + "]")); + return col; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/CustomRenderer.java b/uitest/src/com/vaadin/tests/components/grid/CustomRenderer.java new file mode 100644 index 0000000000..f7d14bbff6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/CustomRenderer.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.Label; + +@Widgetset(TestingWidgetSet.NAME) +public class CustomRenderer extends AbstractTestUI { + + private static final Object INT_ARRAY_PROPERTY = "int array"; + private static final Object VOID_PROPERTY = "void"; + + static final Object ITEM_ID = "itemId1"; + static final String DEBUG_LABEL_ID = "debuglabel"; + static final String INIT_DEBUG_LABEL_CAPTION = "Debug label placeholder"; + + @Override + protected void setup(VaadinRequest request) { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty(INT_ARRAY_PROPERTY, int[].class, + new int[] {}); + container.addContainerProperty(VOID_PROPERTY, Void.class, null); + + Item item = container.addItem(ITEM_ID); + + @SuppressWarnings("unchecked") + Property<int[]> propertyIntArray = item + .getItemProperty(INT_ARRAY_PROPERTY); + propertyIntArray.setValue(new int[] { 1, 1, 2, 3, 5, 8, 13 }); + + Label debugLabel = new Label(INIT_DEBUG_LABEL_CAPTION); + debugLabel.setId(DEBUG_LABEL_ID); + + Grid grid = new Grid(container); + grid.getColumn(INT_ARRAY_PROPERTY).setRenderer(new IntArrayRenderer()); + grid.getColumn(VOID_PROPERTY).setRenderer( + new RowAwareRenderer(debugLabel)); + grid.setSelectionMode(SelectionMode.NONE); + addComponent(grid); + addComponent(debugLabel); + } + + @Override + protected String getTestDescription() { + return "Verifies that renderers operating on other data than " + + "just Strings also work "; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(13334); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java b/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java new file mode 100644 index 0000000000..1c00574f9c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/CustomRendererTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class CustomRendererTest extends MultiBrowserTest { + @Test + public void testIntArrayIsRendered() throws Exception { + openTestURL(); + + GridElement grid = findGrid(); + assertEquals("1 :: 1 :: 2 :: 3 :: 5 :: 8 :: 13", grid.getCell(0, 0) + .getText()); + } + + @Test + public void testRowAwareRenderer() throws Exception { + openTestURL(); + + GridElement grid = findGrid(); + assertEquals("Click me!", grid.getCell(0, 1).getText()); + assertEquals(CustomRenderer.INIT_DEBUG_LABEL_CAPTION, findDebugLabel() + .getText()); + + grid.getCell(0, 1).click(); + assertEquals("row: 0, key: 0", grid.getCell(0, 1).getText()); + assertEquals("key: 0, itemId: " + CustomRenderer.ITEM_ID, + findDebugLabel().getText()); + } + + private GridElement findGrid() { + List<GridElement> elements = $(GridElement.class).all(); + return elements.get(0); + } + + private LabelElement findDebugLabel() { + return $(LabelElement.class).id(CustomRenderer.DEBUG_LABEL_ID); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInit.java b/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInit.java new file mode 100644 index 0000000000..36d92d79a0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInit.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Container.Indexed; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; + +public class GridAddAndRemoveDataOnInit extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid gridAdd = new Grid(); + gridAdd.setHeight("240px"); + gridAdd.setWidth("140px"); + addComponent(gridAdd); + Indexed dataSource = gridAdd.getContainerDataSource(); + dataSource.addContainerProperty("foo", Integer.class, 0); + for (int i = 0; i < 10; ++i) { + Object id = dataSource.addItem(); + dataSource.getItem(id).getItemProperty("foo").setValue(i); + } + dataSource = new IndexedContainer(); + dataSource.addContainerProperty("bar", Integer.class, 0); + for (int i = 0; i < 10; ++i) { + Object id = dataSource.addItem(); + dataSource.getItem(id).getItemProperty("bar").setValue(i); + } + Grid gridRemove = new Grid(dataSource); + gridRemove.setHeight("150px"); + gridRemove.setWidth("140px"); + addComponent(gridRemove); + for (int i = 0; i < 5; ++i) { + dataSource.removeItem(dataSource.getIdByIndex(i)); + } + } + + @Override + protected String getTestDescription() { + return "Foo"; + } + + @Override + protected Integer getTicketNumber() { + return 13334; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java new file mode 100644 index 0000000000..ceaceb661d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridAddAndRemoveDataOnInitTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridAddAndRemoveDataOnInitTest extends MultiBrowserTest { + + @Test + public void verifyGridSizes() { + openTestURL(); + + GridElement gridAdd = $(GridElement.class).first(); + if (!gridAdd.isElementPresent(By.vaadin("#cell[9][0]")) + || gridAdd.isElementPresent(By.vaadin("#cell[10][0]"))) { + Assert.fail("Grid with added data contained incorrect rows"); + } + + GridElement gridRemove = $(GridElement.class).get(1); + if (!gridRemove.isElementPresent(By.vaadin("#cell[4][0]")) + || gridRemove.isElementPresent(By.vaadin("#cell[5][0]"))) { + Assert.fail("Grid with removed data contained incorrect rows"); + } + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridAddRow.java b/uitest/src/com/vaadin/tests/components/grid/GridAddRow.java new file mode 100644 index 0000000000..fa2d7b5399 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridAddRow.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; + +public class GridAddRow extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + + final Grid grid = new Grid(); + grid.setSelectionMode(SelectionMode.MULTI); + grid.addColumn("firstName"); + grid.addColumn("age", Integer.class); + + grid.addRow("Lorem", Integer.valueOf(1)); + grid.addRow("Ipsum", Integer.valueOf(2)); + + addComponent(grid); + + addComponent(new Button("Add new row", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + grid.addRow("Dolor", Integer.valueOf(3)); + } + })); + + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java b/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java new file mode 100644 index 0000000000..46f085686d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridAddRowTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridAddRowTest extends MultiBrowserTest { + @Test + public void testAddRow() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + + Assert.assertEquals("Lorem", grid.getCell(0, 1).getText()); + Assert.assertEquals("2", grid.getCell(1, 2).getText()); + + addRow(); + + Assert.assertEquals("Dolor", grid.getCell(2, 1).getText()); + + addRow(); + + Assert.assertEquals("Dolor", grid.getCell(3, 1).getText()); + } + + private void addRow() { + $(ButtonElement.class).caption("Add new row").first().click(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java b/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java new file mode 100644 index 0000000000..00db02bef3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridClientRenderers.java @@ -0,0 +1,292 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.NativeButtonElement; +import com.vaadin.testbench.elements.NativeSelectElement; +import com.vaadin.testbench.elements.ServerClass; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; +import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererConnector.Renderers; +import com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers; + +/** + * Tests Grid client side renderers + * + * @since + * @author Vaadin Ltd + */ +@TestCategory("grid") +public class GridClientRenderers extends MultiBrowserTest { + + private static final double SLEEP_MULTIPLIER = 1.2; + private int latency = 0; + + @Override + protected Class<?> getUIClass() { + return GridClientColumnRenderers.class; + } + + @Override + protected String getDeploymentPath() { + String path = super.getDeploymentPath(); + if (latency > 0) { + path += (path.contains("?") ? "&" : "?") + "latency=" + latency; + } + return path; + } + + @ServerClass("com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers.GridController") + public static class MyClientGridElement extends GridElement { + } + + @Override + public void setup() throws Exception { + latency = 0; // reset + super.setup(); + } + + @Test + public void addWidgetRenderer() throws Exception { + openTestURL(); + + // Add widget renderer column + $(NativeSelectElement.class).first().selectByText( + Renderers.WIDGET_RENDERER.toString()); + $(NativeButtonElement.class).caption("Add").first().click(); + + // Click the button in cell 1,1 + TestBenchElement cell = getGrid().getCell(1, 2); + WebElement gwtButton = cell.findElement(By.tagName("button")); + gwtButton.click(); + + // Should be an alert visible + assertEquals("Button did not contain text \"Clicked\"", "Clicked", + gwtButton.getText()); + } + + @Test + public void detachAndAttachGrid() { + openTestURL(); + + // Add widget renderer column + $(NativeSelectElement.class).first().selectByText( + Renderers.WIDGET_RENDERER.toString()); + $(NativeButtonElement.class).caption("Add").first().click(); + + // Detach and re-attach the Grid + $(NativeButtonElement.class).caption("DetachAttach").first().click(); + + // Click the button in cell 1,1 + TestBenchElement cell = getGrid().getCell(1, 2); + WebElement gwtButton = cell.findElement(By.tagName("button")); + gwtButton.click(); + + // Should be an alert visible + assertEquals("Button did not contain text \"Clicked\"", + gwtButton.getText(), "Clicked"); + } + + @Test + public void rowsWithDataHasStyleName() throws Exception { + + testBench().disableWaitForVaadin(); + + // Simulate network latency with 2000ms + latency = 2000; + + openTestURL(); + + sleep((int) (latency * SLEEP_MULTIPLIER)); + + TestBenchElement row = getGrid().getRow(51); + String className = row.getAttribute("class"); + assertFalse( + "Row should not yet contain style name v-grid-row-has-data", + className.contains("v-grid-row-has-data")); + + // Wait for data to arrive + sleep((int) (latency * SLEEP_MULTIPLIER)); + + row = getGrid().getRow(51); + className = row.getAttribute("class"); + assertTrue("Row should now contain style name v-grid-row-has-data", + className.contains("v-grid-row-has-data")); + } + + @Test + public void complexRendererSetVisibleContent() throws Exception { + + DesiredCapabilities desiredCapabilities = getDesiredCapabilities(); + + // Simulate network latency with 2000ms + latency = 2000; + if (BrowserUtil.isIE8(desiredCapabilities)) { + // IE8 is slower than other browsers. Bigger latency is needed for + // stability in this test. + latency = 3000; + } + + // Chrome uses RGB instead of RGBA + String colorRed = "rgba(255, 0, 0, 1)"; + String colorWhite = "rgba(255, 255, 255, 1)"; + String colorDark = "rgba(239, 240, 241, 1)"; + if (BrowserUtil.isChrome(desiredCapabilities)) { + colorRed = "rgb(255, 0, 0)"; + colorWhite = "rgb(255, 255, 255)"; + colorDark = "rgb(239, 240, 241)"; + } + + openTestURL(); + + getGrid(); + + testBench().disableWaitForVaadin(); + + // Test initial renderering with contentVisible = False + TestBenchElement cell = getGrid().getCell(51, 1); + String backgroundColor = cell.getCssValue("backgroundColor"); + assertEquals("Background color was not red.", colorRed, backgroundColor); + + // data arrives... + sleep((int) (latency * SLEEP_MULTIPLIER)); + + // Content becomes visible + cell = getGrid().getCell(51, 1); + backgroundColor = cell.getCssValue("backgroundColor"); + assertNotEquals("Background color was red.", colorRed, backgroundColor); + + // scroll down, new cells becomes contentVisible = False + getGrid().scrollToRow(60); + + // Cell should be red (setContentVisible set cell red) + cell = getGrid().getCell(55, 1); + backgroundColor = cell.getCssValue("backgroundColor"); + assertEquals("Background color was not red.", colorRed, backgroundColor); + + // data arrives... + sleep((int) (latency * SLEEP_MULTIPLIER)); + + // Cell should no longer be red + backgroundColor = cell.getCssValue("backgroundColor"); + assertTrue( + "Background color was not reset", + backgroundColor.equals(colorWhite) + || backgroundColor.equals(colorDark)); + } + + @Test + public void testSortingEvent() throws Exception { + openTestURL(); + + $(NativeButtonElement.class).caption("Trigger sorting event").first() + .click(); + + String consoleText = $(LabelElement.class).id("testDebugConsole") + .getText(); + + assertTrue("Console text as expected", + consoleText.contains("Columns: 1, order: Column 1: ASCENDING")); + + } + + @Test + public void testListSorter() throws Exception { + openTestURL(); + + $(NativeButtonElement.class).caption("Shuffle").first().click(); + + GridElement gridElem = $(MyClientGridElement.class).first(); + + // XXX: DANGER! We'll need to know how many rows the Grid has! + // XXX: Currently, this is impossible; hence the hardcoded value of 70. + + boolean shuffled = false; + for (int i = 1, l = 70; i < l; ++i) { + + String str_a = gridElem.getCell(i - 1, 0).getAttribute("innerHTML"); + String str_b = gridElem.getCell(i, 0).getAttribute("innerHTML"); + + int value_a = Integer.parseInt(str_a); + int value_b = Integer.parseInt(str_b); + + if (value_a > value_b) { + shuffled = true; + break; + } + } + assertTrue("Grid shuffled", shuffled); + + $(NativeButtonElement.class).caption("Test sorting").first().click(); + + for (int i = 1, l = 70; i < l; ++i) { + + String str_a = gridElem.getCell(i - 1, 0).getAttribute("innerHTML"); + String str_b = gridElem.getCell(i, 0).getAttribute("innerHTML"); + + int value_a = Integer.parseInt(str_a); + int value_b = Integer.parseInt(str_b); + + if (value_a > value_b) { + assertTrue("Grid sorted", false); + } + } + } + + @Test + public void testComplexRendererOnActivate() { + openTestURL(); + + GridCellElement cell = getGrid().getCell(3, 1); + cell.click(); + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + + assertEquals("onActivate was not called on KeyDown Enter.", + "Activated!", cell.getText()); + + cell = getGrid().getCell(4, 1); + cell.click(); + new Actions(getDriver()).moveToElement(cell).doubleClick().perform(); + assertEquals("onActivate was not called on double click.", + "Activated!", cell.getText()); + } + + private GridElement getGrid() { + return $(MyClientGridElement.class).first(); + } + + private void addColumn(Renderers renderer) { + // Add widget renderer column + $(NativeSelectElement.class).first().selectByText(renderer.toString()); + $(NativeButtonElement.class).caption("Add").first().click(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColspans.java b/uitest/src/com/vaadin/tests/components/grid/GridColspans.java new file mode 100644 index 0000000000..80337971b6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColspans.java @@ -0,0 +1,102 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Container.Indexed; +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.FooterRow; +import com.vaadin.ui.Grid.HeaderRow; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.renderer.NumberRenderer; + +public class GridColspans extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Indexed dataSource = new IndexedContainer(); + final Grid grid; + + dataSource.addContainerProperty("firstName", String.class, ""); + dataSource.addContainerProperty("lastName", String.class, ""); + dataSource.addContainerProperty("streetAddress", String.class, ""); + dataSource.addContainerProperty("zipCode", Integer.class, null); + dataSource.addContainerProperty("city", String.class, ""); + Item i = dataSource.addItem(0); + i.getItemProperty("firstName").setValue("Rudolph"); + i.getItemProperty("lastName").setValue("Reindeer"); + i.getItemProperty("streetAddress").setValue("Ruukinkatu 2-4"); + i.getItemProperty("zipCode").setValue(20540); + i.getItemProperty("city").setValue("Turku"); + grid = new Grid(dataSource); + grid.setWidth("600px"); + grid.getColumn("zipCode").setRenderer(new NumberRenderer()); + grid.setSelectionMode(SelectionMode.MULTI); + addComponent(grid); + + HeaderRow row = grid.prependHeaderRow(); + row.join("firstName", "lastName").setText("Full Name"); + row.join("streetAddress", "zipCode", "city").setText("Address"); + grid.prependHeaderRow() + .join(dataSource.getContainerPropertyIds().toArray()) + .setText("All the stuff"); + + FooterRow footerRow = grid.appendFooterRow(); + footerRow.join("firstName", "lastName").setText("Full Name"); + footerRow.join("streetAddress", "zipCode", "city").setText("Address"); + grid.appendFooterRow() + .join(dataSource.getContainerPropertyIds().toArray()) + .setText("All the stuff"); + + addComponent(new Button("Show/Hide firstName", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + if (grid.getColumn("firstName") != null) { + grid.removeColumn("firstName"); + } else { + grid.addColumn("firstName"); + } + } + })); + + addComponent(new Button("Change column order", + new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + grid.setColumnOrder("zipCode", "firstName"); + } + })); + } + + @Override + protected String getTestDescription() { + return "Grid header and footer colspans"; + } + + @Override + protected Integer getTicketNumber() { + return 13334; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java new file mode 100644 index 0000000000..6b50b64732 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColspansTest.java @@ -0,0 +1,101 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridColspansTest extends MultiBrowserTest { + + @Before + public void setUp() { + setDebug(true); + } + + @Test + public void testHeaderColSpans() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + assertEquals("5", grid.getHeaderCell(0, 1).getAttribute("colspan")); + assertEquals("2", grid.getHeaderCell(1, 1).getAttribute("colspan")); + assertEquals("3", grid.getHeaderCell(1, 3).getAttribute("colspan")); + } + + @Test + public void testFooterColSpans() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + assertEquals("5", grid.getFooterCell(1, 1).getAttribute("colspan")); + assertEquals("2", grid.getFooterCell(0, 1).getAttribute("colspan")); + assertEquals("3", grid.getFooterCell(0, 3).getAttribute("colspan")); + } + + @Test + public void testHideFirstColumnOfColspan() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + assertEquals("Failed initial condition.", "all the stuff", grid + .getHeaderCell(0, 1).getText().toLowerCase()); + assertEquals("Failed initial condition.", "first name", grid + .getHeaderCell(2, 1).getText().toLowerCase()); + $(ButtonElement.class).caption("Show/Hide firstName").first().click(); + assertEquals("Header text changed on column hide.", "all the stuff", + grid.getHeaderCell(0, 1).getText().toLowerCase()); + assertEquals("Failed initial condition.", "last name", grid + .getHeaderCell(2, 1).getText().toLowerCase()); + } + + @Test + public void testSplittingMergedHeaders() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + GridCellElement headerCell = grid.getHeaderCell(1, 1); + assertEquals("Failed initial condition.", "full name", headerCell + .getText().toLowerCase()); + assertEquals("Failed initial condition.", "first name", grid + .getHeaderCell(2, 1).getText().toLowerCase()); + $(ButtonElement.class).get(1).click(); + headerCell = grid.getHeaderCell(1, 1); + assertEquals("Header text not changed on column reorder.", "address", + headerCell.getText().toLowerCase()); + assertEquals("Unexpected colspan", "1", + headerCell.getAttribute("colspan")); + headerCell = grid.getHeaderCell(1, 2); + assertEquals("Header text not changed on column reorder", "full name", + headerCell.getText().toLowerCase()); + assertEquals("Unexpected colspan", "2", + headerCell.getAttribute("colspan")); + + assertTrue("Error indicator not present", + isElementPresent(By.className("v-errorindicator"))); + + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidth.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidth.java new file mode 100644 index 0000000000..98fa1ab6fd --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidth.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Container; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.Column; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.renderer.HtmlRenderer; + +public class GridColumnAutoWidth extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(createContainer()); + grid.getColumn("fixed width narrow").setWidth(50); + grid.getColumn("fixed width wide").setWidth(200); + + for (Object propertyId : grid.getContainerDataSource() + .getContainerPropertyIds()) { + Column column = grid.getColumn(propertyId); + column.setExpandRatio(0); + column.setRenderer(new HtmlRenderer()); + grid.getHeaderRow(0).getCell(propertyId) + .setHtml("<span>" + column.getHeaderCaption() + "</span>"); + } + + grid.setSelectionMode(SelectionMode.NONE); + grid.setWidth("700px"); + addComponent(grid); + } + + private static Container.Indexed createContainer() { + IndexedContainer c = new IndexedContainer(); + c.addContainerProperty("equal width", String.class, + "<span>equal width</span>"); + c.addContainerProperty("short", String.class, + "<span>a very long cell content</span>"); + c.addContainerProperty("a very long header content", String.class, + "<span>short</span>"); + c.addContainerProperty("fixed width narrow", String.class, + "<span>fixed width narrow</span>"); + c.addContainerProperty("fixed width wide", String.class, + "<span>fixed width wide</span>"); + c.addItem(); + return c; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClient.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClient.java new file mode 100644 index 0000000000..0829e09de9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClient.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridColumnAutoWidthClientWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; + +@Widgetset(TestingWidgetSet.NAME) +public class GridColumnAutoWidthClient extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + addComponent(new TestWidgetComponent( + GridColumnAutoWidthClientWidget.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java new file mode 100644 index 0000000000..dcc14a967d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthClientTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.tests.annotations.TestCategory; + +@TestCategory("grid") +public class GridColumnAutoWidthClientTest extends + AbstractGridColumnAutoWidthTest { + @Override + protected Class<?> getUIClass() { + return GridColumnAutoWidthClient.class; + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java new file mode 100644 index 0000000000..2f42b89eb1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnAutoWidthServerTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.tests.annotations.TestCategory; + +@TestCategory("grid") +public class GridColumnAutoWidthServerTest extends + AbstractGridColumnAutoWidthTest { + @Override + protected Class<?> getUIClass() { + return GridColumnAutoWidth.class; + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/grid/GridColumnExpand.java b/uitest/src/com/vaadin/tests/components/grid/GridColumnExpand.java new file mode 100644 index 0000000000..f8338f991a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridColumnExpand.java @@ -0,0 +1,159 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Component; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.Column; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.themes.Reindeer; + +@Theme(Reindeer.THEME_NAME) +public class GridColumnExpand extends AbstractTestUI { + private Grid grid; + private Label firstInfo = new Label(); + private Label secondInfo = new Label(); + private Column firstColumn; + private Column secondColumn; + + @Override + protected void setup(VaadinRequest request) { + grid = new Grid(PersonContainer.createWithTestData()); + grid.removeAllColumns(); + grid.addColumn("address.streetAddress"); + grid.addColumn("lastName"); + firstColumn = grid.getColumns().get(0); + secondColumn = grid.getColumns().get(1); + + updateInfoLabels(); + addComponent(grid); + addComponent(firstInfo); + addComponent(secondInfo); + addButtons(); + } + + private void addButtons() { + HorizontalLayout layout = new HorizontalLayout(); + layout.addComponent(createButtons(firstColumn)); + layout.addComponent(createButtons(secondColumn)); + layout.setExpandRatio(layout.getComponent(1), 1); + addComponent(layout); + } + + private Component createButtons(Column column) { + CssLayout layout = new CssLayout(); + layout.addComponent(new Label("Column 1")); + + CssLayout widthLayout = new CssLayout(); + layout.addComponent(widthLayout); + widthLayout.addComponent(new Label("Width")); + widthLayout.addComponent(createWidthButton(column, -1)); + widthLayout.addComponent(createWidthButton(column, 50)); + widthLayout.addComponent(createWidthButton(column, 200)); + + CssLayout minLayout = new CssLayout(); + layout.addComponent(minLayout); + minLayout.addComponent(new Label("Min width")); + minLayout.addComponent(createMinButton(column, -1)); + minLayout.addComponent(createMinButton(column, 50)); + minLayout.addComponent(createMinButton(column, 200)); + + CssLayout maxLayout = new CssLayout(); + maxLayout.addComponent(new Label("Max width")); + maxLayout.addComponent(createMaxButton(column, -1)); + maxLayout.addComponent(createMaxButton(column, 50)); + maxLayout.addComponent(createMaxButton(column, 200)); + layout.addComponent(maxLayout); + + CssLayout expandLayout = new CssLayout(); + expandLayout.addComponent(new Label("Expand ratio")); + expandLayout.addComponent(createExpandButton(column, -1)); + expandLayout.addComponent(createExpandButton(column, 0)); + expandLayout.addComponent(createExpandButton(column, 1)); + expandLayout.addComponent(createExpandButton(column, 2)); + layout.addComponent(expandLayout); + + return layout; + } + + private Component createWidthButton(final Column column, final double width) { + return new Button("" + width, new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + if (width >= 0) { + column.setWidth(width); + } else { + column.setWidthUndefined(); + } + updateInfoLabels(); + } + }); + } + + private Component createMinButton(final Column column, final double width) { + return new Button("" + width, new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + column.setMinimumWidth(width); + updateInfoLabels(); + } + }); + } + + private Component createMaxButton(final Column column, final double width) { + return new Button("" + width, new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + column.setMaximumWidth(width); + updateInfoLabels(); + } + }); + } + + private Component createExpandButton(final Column column, final int ratio) { + return new Button("" + ratio, new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + column.setExpandRatio(ratio); + updateInfoLabels(); + } + }); + } + + private void updateInfoLabels() { + updateLabel(firstInfo, firstColumn); + updateLabel(secondInfo, secondColumn); + } + + private void updateLabel(Label label, Column column) { + int expandRatio = column.getExpandRatio(); + double minimumWidth = Math.round(column.getMinimumWidth() * 100) / 100; + double maximumWidth = Math.round(column.getMaximumWidth() * 100) / 100; + double width = Math.round(column.getWidth() * 100) / 100; + Object propertyId = column.getPropertyId(); + label.setValue(String.format( + "[%s] Expand ratio: %s - min: %s - max: %s - width: %s", + propertyId, expandRatio, minimumWidth, maximumWidth, width)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorUI.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorUI.java new file mode 100644 index 0000000000..fe4b4342a2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorUI.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.ui.Grid; +import com.vaadin.ui.PasswordField; +import com.vaadin.ui.TextField; + +public class GridEditorUI extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + PersonContainer container = PersonContainer.createWithTestData(); + + Grid grid = new Grid(container); + + // Don't use address since there's no converter + grid.removeColumn("address"); + + grid.setEditorEnabled(true); + + grid.setEditorField("firstName", new PasswordField()); + + TextField lastNameField = (TextField) grid + .getEditorField("lastName"); + lastNameField.setMaxLength(50); + + grid.getEditorField("phoneNumber").setReadOnly(true); + + addComponent(grid); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java b/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java new file mode 100644 index 0000000000..6c386eec03 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridEditorUITest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.testbench.elements.PasswordFieldElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridEditorUITest extends MultiBrowserTest { + + @Test + public void testEditor() { + setDebug(true); + openTestURL(); + + assertFalse("Sanity check", + isElementPresent(PasswordFieldElement.class)); + + openEditor(5); + new Actions(getDriver()).sendKeys(Keys.ESCAPE).perform(); + + openEditor(10); + + assertTrue("Edtor should be opened with a password field", + isElementPresent(PasswordFieldElement.class)); + + assertFalse("Notification was present", + isElementPresent(NotificationElement.class)); + } + + private void openEditor(int rowIndex) { + GridElement grid = $(GridElement.class).first(); + + GridCellElement cell = grid.getCell(rowIndex, 1); + + new Actions(driver).moveToElement(cell).doubleClick().build().perform(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridGeneratedProperties.java b/uitest/src/com/vaadin/tests/components/grid/GridGeneratedProperties.java new file mode 100644 index 0000000000..2782a5fc6c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridGeneratedProperties.java @@ -0,0 +1,165 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.Container.Filterable; +import com.vaadin.data.Container.Indexed; +import com.vaadin.data.Item; +import com.vaadin.data.sort.Sort; +import com.vaadin.data.sort.SortOrder; +import com.vaadin.data.util.GeneratedPropertyContainer; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.data.util.PropertyValueGenerator; +import com.vaadin.data.util.filter.Compare; +import com.vaadin.data.util.filter.UnsupportedFilterException; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.data.sort.SortDirection; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Grid; + +public class GridGeneratedProperties extends AbstractTestUI { + + private GeneratedPropertyContainer container; + static double MILES_CONVERSION = 0.6214d; + private Filter filter = new Compare.Greater("miles", 1d); + + @Override + protected void setup(VaadinRequest request) { + container = new GeneratedPropertyContainer(createContainer()); + Grid grid = new Grid(container); + addComponent(grid); + + container.addGeneratedProperty("miles", + new PropertyValueGenerator<Double>() { + + @Override + public Double getValue(Item item, Object itemId, + Object propertyId) { + return (Double) item.getItemProperty("km").getValue() + * MILES_CONVERSION; + } + + @Override + public Class<Double> getType() { + return Double.class; + } + + @Override + public Filter modifyFilter(Filter filter) + throws UnsupportedFilterException { + if (filter instanceof Compare.Greater) { + Double value = (Double) ((Compare.Greater) filter) + .getValue(); + value = value / MILES_CONVERSION; + return new Compare.Greater("km", value); + } + return super.modifyFilter(filter); + } + }); + + final Button filterButton = new Button("Add filter"); + filterButton.addClickListener(new ClickListener() { + + boolean active = false; + + @Override + public void buttonClick(ClickEvent event) { + if (active) { + ((Filterable) container).removeContainerFilter(filter); + filterButton.setCaption("Add filter"); + active = false; + return; + } + ((Filterable) container).addContainerFilter(filter); + filterButton.setCaption("Remove filter"); + active = true; + } + }); + + container.addGeneratedProperty("foo", + new PropertyValueGenerator<String>() { + + @Override + public String getValue(Item item, Object itemId, + Object propertyId) { + return item.getItemProperty("foo").getValue() + " " + + item.getItemProperty("bar").getValue(); + } + + @Override + public Class<String> getType() { + return String.class; + } + }); + container.removeContainerProperty("bar"); + container.addGeneratedProperty("baz", + new PropertyValueGenerator<Integer>() { + + @Override + public Integer getValue(Item item, Object itemId, + Object propertyId) { + return (Integer) item.getItemProperty("bar").getValue(); + } + + @Override + public Class<Integer> getType() { + return Integer.class; + } + + @Override + public SortOrder[] getSortProperties(SortOrder order) { + return Sort.by("bar", order.getDirection()).build() + .toArray(new SortOrder[1]); + } + }); + + addComponent(filterButton); + grid.sort(Sort.by("km").then("bar", SortDirection.DESCENDING)); + } + + private Indexed createContainer() { + Indexed container = new IndexedContainer(); + container.addContainerProperty("foo", String.class, "foo"); + container.addContainerProperty("bar", Integer.class, 0); + // km contains double values from 0.0 to 2.0 + container.addContainerProperty("km", Double.class, 0); + + for (int i = 0; i <= 100; ++i) { + Object itemId = container.addItem(); + Item item = container.getItem(itemId); + item.getItemProperty("foo").setValue("foo"); + item.getItemProperty("bar").setValue(i); + item.getItemProperty("km").setValue(i / 5.0d); + } + + return container; + } + + @Override + protected String getTestDescription() { + return "A Grid with GeneratedPropertyContainer"; + } + + @Override + protected Integer getTicketNumber() { + return 13334; + } + +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java b/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java new file mode 100644 index 0000000000..ffcd4c448f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridGeneratedPropertiesTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridGeneratedPropertiesTest extends MultiBrowserTest { + + @Test + public void testMilesColumnExists() { + openTestURL(); + GridElement grid = $(GridElement.class).first(); + assertEquals("Miles header wasn't present.", "miles", grid + .getHeaderCell(0, 2).getText().toLowerCase()); + } + + @Test + public void testUnsortableGeneratedProperty() { + openTestURL(); + GridElement grid = $(GridElement.class).first(); + + // Overwritten foo property should not be sortable + GridCellElement fooHeader = grid.getHeaderCell(0, 0); + fooHeader.click(); + assertFalse("Column foo was unexpectedly sorted.", fooHeader + .getAttribute("class").contains("sort")); + + // Generated property miles is not sortable + GridCellElement milesHeader = grid.getHeaderCell(0, 2); + milesHeader.click(); + assertFalse("Column miles was unexpectedly sorted.", milesHeader + .getAttribute("class").contains("sort")); + } + + @Test + public void testSortableGeneratedProperty() { + openTestURL(); + GridElement grid = $(GridElement.class).first(); + + // Generated property baz is sortable + GridCellElement bazHeader = grid.getHeaderCell(0, 3); + bazHeader.click(); + assertTrue("Column baz was not sorted ascending", bazHeader + .getAttribute("class").contains("sort-asc")); + bazHeader.click(); + assertTrue("Column baz was not sorted descending", bazHeader + .getAttribute("class").contains("sort-desc")); + } + + @Test + public void testInitialSorting() { + // Grid is sorted in this case by one visible and one nonexistent + // column. There should be no sort indicator. + setDebug(true); + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + + GridCellElement kmHeader = grid.getHeaderCell(0, 1); + assertFalse("Column km was unexpectedly sorted", + kmHeader.getAttribute("class").contains("sort-asc") + || kmHeader.getAttribute("class").contains("sort-desc")); + assertFalse("Unexpected client-side exception was visible", + isElementPresent(NotificationElement.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNames.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNames.java new file mode 100644 index 0000000000..765cd01812 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNames.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.tests.components.beanitemcontainer.BeanItemContainerGenerator; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.FooterCell; +import com.vaadin.ui.Grid.FooterRow; +import com.vaadin.ui.Grid.HeaderCell; +import com.vaadin.ui.Grid.HeaderRow; +import com.vaadin.ui.Grid.SelectionMode; + +@Theme("valo") +public class GridHeaderStyleNames extends AbstractTestUIWithLog { + + private HeaderCell ageHeaderCell; + private HeaderCell mergedCityCountryCell; + private FooterCell ageFooterCell; + private HeaderRow headerRow; + private FooterRow footerRow; + + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(); + grid.setSelectionMode(SelectionMode.MULTI); + grid.setContainerDataSource(BeanItemContainerGenerator + .createContainer(100)); + + ageHeaderCell = grid.getDefaultHeaderRow().getCell("age"); + + headerRow = grid.prependHeaderRow(); + mergedCityCountryCell = headerRow.join("city", "country"); + mergedCityCountryCell.setText("Merged cell"); + addComponent(grid); + + footerRow = grid.appendFooterRow(); + ageFooterCell = footerRow.getCell("age"); + + getPage() + .getStyles() + .add(".age {background-image: linear-gradient(to bottom,green 2%, #efefef 98%) !important;}"); + getPage() + .getStyles() + .add(".valo .v-grid-header .v-grid-cell.city-country {background-image: linear-gradient(to bottom,yellow 2%, #efefef 98%) !important;}"); + getPage() + .getStyles() + .add(".valo .v-grid-footer .v-grid-cell.age-footer {background-image: linear-gradient(to bottom,blue 2%, #efefef 98%) !important;}"); + getPage() + .getStyles() + .add(".valo .v-grid .v-grid-row.custom-row > * {background-image: linear-gradient(to bottom,purple 2%, #efefef 98%);}"); + + setCellStyles(true); + setRowStyles(true); + + Button b = new Button("Toggle styles"); + b.addClickListener(new ClickListener() { + private boolean stylesOn = true; + + @Override + public void buttonClick(ClickEvent event) { + setCellStyles(!stylesOn); + setRowStyles(!stylesOn); + stylesOn = !stylesOn; + } + }); + addComponent(b); + } + + protected void setCellStyles(boolean set) { + if (set) { + ageHeaderCell.setStyleName("age"); + ageFooterCell.setStyleName("age-footer"); + mergedCityCountryCell.setStyleName("city-country"); + } else { + ageHeaderCell.setStyleName(null); + ageFooterCell.setStyleName(null); + mergedCityCountryCell.setStyleName(null); + } + + } + + protected void setRowStyles(boolean set) { + if (set) { + headerRow.setStyleName("custom-row"); + footerRow.setStyleName("custom-row"); + } else { + headerRow.setStyleName(null); + footerRow.setStyleName(null); + } + + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java new file mode 100644 index 0000000000..0f70d66ad4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridHeaderStyleNamesTest.java @@ -0,0 +1,158 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.SingleBrowserTest; + +@TestCategory("grid") +public class GridHeaderStyleNamesTest extends SingleBrowserTest { + + private GridElement grid; + + @Before + public void findGridCells() { + openTestURL(); + grid = $(GridElement.class).first(); + } + + private GridCellElement getMergedHeaderCell() { + return grid.getHeaderCell(0, 3); + } + + private GridCellElement getAgeFooterCell() { + return grid.getFooterCell(0, 2); + } + + @Test + public void cellStyleNamesCanBeAddedAndRemoved() { + ButtonElement toggleStyles = $(ButtonElement.class).caption( + "Toggle styles").first(); + + assertStylesSet(true); + toggleStyles.click(); + assertStylesSet(false); + toggleStyles.click(); + assertStylesSet(true); + } + + @Test + public void rowStyleNamesCanBeAddedAndRemoved() { + ButtonElement toggleStyles = $(ButtonElement.class).caption( + "Toggle styles").first(); + + assertRowStylesSet(true); + toggleStyles.click(); + assertRowStylesSet(false); + toggleStyles.click(); + assertRowStylesSet(true); + + } + + private void assertStylesSet(boolean set) { + if (set) { + assertHasStyleName( + "Footer cell should have the assigned 'age-footer' class name", + getAgeFooterCell(), "age-footer"); + assertHasStyleName( + "Header cell should have the assigned 'age' class name", + getAgeHeaderCell(), "age"); + assertHasStyleName( + "The merged header cell should have the assigned 'city-country' class name", + getMergedHeaderCell(), "city-country"); + } else { + assertHasNotStyleName( + "Footer cell should not have the removed 'age-footer' class name", + getAgeFooterCell(), "age-footer"); + assertHasNotStyleName( + "Header cell should not have the removed 'age' class name", + getAgeHeaderCell(), "age"); + assertHasNotStyleName( + "Ther merged header cell should not have the removed 'city-country' class name", + getMergedHeaderCell(), "city-country"); + } + assertHasStyleName( + "The default v-grid-cell style name should not be removed from the header cell", + getAgeHeaderCell(), "v-grid-cell"); + assertHasStyleName( + "The default v-grid-cell style name should not be removed from the footer cell", + getAgeFooterCell(), "v-grid-cell"); + assertHasStyleName( + "The default v-grid-cell style name should not be removed from the merged header cell", + getMergedHeaderCell(), "v-grid-cell"); + + } + + private void assertRowStylesSet(boolean set) { + if (set) { + assertHasStyleName( + "Footer row should have the assigned 'custom-row' class name", + getFooterRow(), "custom-row"); + assertHasStyleName( + "Header row should have the assigned 'custom-row' class name", + getHeaderRow(), "custom-row"); + } else { + assertHasNotStyleName( + "Footer row should not have the removed 'custom-row' class name", + getFooterRow(), "custom-row"); + assertHasNotStyleName( + "Header row should not have the removed 'custom-row' class name", + getHeaderRow(), "custom-row"); + } + assertHasStyleName( + "The default v-grid-row style name should not be removed from the header row", + getHeaderRow(), "v-grid-row"); + assertHasStyleName( + "The default v-grid-row style name should not be removed from the footer row", + getFooterRow(), "v-grid-row"); + + } + + private WebElement getAgeHeaderCell() { + return grid.getHeaderCell(1, 2); + } + + private WebElement getFooterRow() { + return grid.getFooterRow(0); + } + + private WebElement getHeaderRow() { + return grid.getHeaderRow(0); + } + + private void assertHasStyleName(String message, WebElement element, + String stylename) { + if (!hasCssClass(element, stylename)) { + Assert.fail(message); + } + } + + private void assertHasNotStyleName(String message, WebElement element, + String stylename) { + if (hasCssClass(element, stylename)) { + Assert.fail(message); + } + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridInTabSheet.java b/uitest/src/com/vaadin/tests/components/grid/GridInTabSheet.java new file mode 100644 index 0000000000..6c7f254a0d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridInTabSheet.java @@ -0,0 +1,69 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.Label; +import com.vaadin.ui.TabSheet; + +public class GridInTabSheet extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + TabSheet sheet = new TabSheet(); + final Grid grid = new Grid(); + grid.setSelectionMode(SelectionMode.MULTI); + grid.addColumn("count", Integer.class); + for (Integer i = 0; i < 3; ++i) { + grid.addRow(i); + } + + sheet.addTab(grid); + sheet.addTab(new Label("Hidden")); + + addComponent(sheet); + addComponent(new Button("Add row to Grid", new Button.ClickListener() { + + private Integer k = 0; + + @Override + public void buttonClick(ClickEvent event) { + grid.addRow(100 + (k++)); + } + })); + addComponent(new Button("Remove row from Grid", + new Button.ClickListener() { + + private Integer k = 0; + + @Override + public void buttonClick(ClickEvent event) { + Object firstItemId = grid.getContainerDataSource() + .firstItemId(); + if (firstItemId != null) { + grid.getContainerDataSource().removeItem( + firstItemId); + } + } + })); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java b/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java new file mode 100644 index 0000000000..cd165e4678 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridInTabSheetTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridInTabSheetTest extends MultiBrowserTest { + + @Test + public void testRemoveAllRowsAndAddThreeNewOnes() { + setDebug(true); + openTestURL(); + + for (int i = 0; i < 3; ++i) { + removeGridRow(); + } + + for (int i = 0; i < 3; ++i) { + addGridRow(); + assertEquals("" + (100 + i), getGridElement().getCell(i, 1) + .getText()); + } + assertFalse("There was an unexpected error notification", + isElementPresent(NotificationElement.class)); + } + + private void removeGridRow() { + $(ButtonElement.class).caption("Remove row from Grid").first().click(); + } + + private void addGridRow() { + $(ButtonElement.class).caption("Add row to Grid").first().click(); + } + + private GridElement getGridElement() { + return $(GridElement.class).first(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridMultiSelectionOnInit.java b/uitest/src/com/vaadin/tests/components/grid/GridMultiSelectionOnInit.java new file mode 100644 index 0000000000..10d4977623 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridMultiSelectionOnInit.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; + +public class GridMultiSelectionOnInit extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(); + grid.addColumn("foo", String.class); + grid.addRow("Foo 1"); + grid.addRow("Foo 2"); + grid.setSelectionMode(SelectionMode.MULTI); + addComponent(grid); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridMultiSelectionOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/GridMultiSelectionOnInitTest.java new file mode 100644 index 0000000000..5f5b4df8de --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridMultiSelectionOnInitTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridMultiSelectionOnInitTest extends MultiBrowserTest { + + @Test + public void testSelectAllCheckBoxExists() { + openTestURL(); + assertTrue("The select all checkbox was missing.", + $(GridElement.class).first().getHeaderCell(0, 0) + .isElementPresent(By.tagName("input"))); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridScrolling.java b/uitest/src/com/vaadin/tests/components/grid/GridScrolling.java new file mode 100644 index 0000000000..ce64b3e9f3 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridScrolling.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.grid.ScrollDestination; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.VerticalLayout; + +@SuppressWarnings("serial") +public class GridScrolling extends AbstractTestUI { + + private Grid grid; + + private IndexedContainer ds; + + @Override + @SuppressWarnings("unchecked") + protected void setup(VaadinRequest request) { + // Build data source + ds = new IndexedContainer(); + + for (int col = 0; col < 5; col++) { + ds.addContainerProperty("col" + col, String.class, ""); + } + + for (int row = 0; row < 65536; row++) { + Item item = ds.addItem(Integer.valueOf(row)); + for (int col = 0; col < 5; col++) { + item.getItemProperty("col" + col).setValue( + "(" + row + ", " + col + ")"); + } + } + + grid = new Grid(ds); + + HorizontalLayout hl = new HorizontalLayout(); + hl.addComponent(grid); + hl.setMargin(true); + hl.setSpacing(true); + + VerticalLayout vl = new VerticalLayout(); + vl.setSpacing(true); + + // Add scroll buttons + Button scrollUpButton = new Button("Top", new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + grid.scrollToStart(); + } + }); + scrollUpButton.setSizeFull(); + vl.addComponent(scrollUpButton); + + for (int i = 1; i < 7; ++i) { + final int row = (ds.size() / 7) * i; + Button scrollButton = new Button("Scroll to row " + row, + new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + grid.scrollTo(Integer.valueOf(row), + ScrollDestination.MIDDLE); + } + }); + scrollButton.setSizeFull(); + vl.addComponent(scrollButton); + } + + Button scrollDownButton = new Button("Bottom", new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + grid.scrollToEnd(); + } + }); + scrollDownButton.setSizeFull(); + vl.addComponent(scrollDownButton); + + hl.addComponent(vl); + addComponent(hl); + } + + @Override + protected String getTestDescription() { + return "Test Grid programmatic scrolling features"; + } + + @Override + protected Integer getTicketNumber() { + return 13327; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridSingleColumn.java b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumn.java new file mode 100644 index 0000000000..2ab0282102 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumn.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.Column; +import com.vaadin.ui.Grid.SelectionMode; + +public class GridSingleColumn extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + + IndexedContainer indexedContainer = new IndexedContainer(); + indexedContainer.addContainerProperty("column1", String.class, ""); + + for (int i = 0; i < 100; i++) { + Item addItem = indexedContainer.addItem(i); + addItem.getItemProperty("column1").setValue("cell"); + } + + Grid grid = new Grid(indexedContainer); + grid.setSelectionMode(SelectionMode.NONE); + + Column column = grid.getColumn("column1"); + + column.setHeaderCaption("Header"); + + addComponent(grid); + grid.scrollTo(grid.getContainerDataSource().getIdByIndex(50)); + } + + @Override + protected String getTestDescription() { + return "Tests a single column grid"; + } + + @Override + protected Integer getTicketNumber() { + return null; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java new file mode 100644 index 0000000000..42eb2197bf --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridSingleColumnTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridSingleColumnTest extends MultiBrowserTest { + + @Test + public void testHeaderIsVisible() { + openTestURL(); + + GridCellElement cell = $(GridElement.class).first().getHeaderCell(0, 0); + Assert.assertTrue("No header available", cell.getText() + .equalsIgnoreCase("header")); + } + + @Test + public void testScrollDidNotThrow() { + setDebug(true); + openTestURL(); + + Assert.assertFalse("Exception when scrolling on init", + isElementPresent(NotificationElement.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridThemeChange.java b/uitest/src/com/vaadin/tests/components/grid/GridThemeChange.java new file mode 100644 index 0000000000..76f7e22ee0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridThemeChange.java @@ -0,0 +1,59 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import java.util.Arrays; +import java.util.List; + +import com.vaadin.event.SelectionEvent; +import com.vaadin.event.SelectionEvent.SelectionListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; + +public class GridThemeChange extends AbstractTestUI { + private final List<String> themes = Arrays.asList("valo", "reindeer", + "runo", "chameleon", "base"); + + @Override + protected void setup(VaadinRequest request) { + final Grid grid = new Grid(); + grid.setSelectionMode(SelectionMode.SINGLE); + + grid.addColumn("Theme"); + for (String theme : themes) { + Object itemId = grid.addRow(theme); + if (theme.equals(getTheme())) { + grid.select(itemId); + } + } + + grid.addSelectionListener(new SelectionListener() { + @Override + public void select(SelectionEvent event) { + Object selectedItemId = grid.getSelectedRow(); + Object theme = grid.getContainerDataSource() + .getItem(selectedItemId).getItemProperty("Theme") + .getValue(); + setTheme(String.valueOf(theme)); + } + }); + + addComponent(grid); + + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridThemeChangeTest.java b/uitest/src/com/vaadin/tests/components/grid/GridThemeChangeTest.java new file mode 100644 index 0000000000..5a21705b55 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridThemeChangeTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class GridThemeChangeTest extends MultiBrowserTest { + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + // Seems like stylesheet onload is not fired on PhantomJS + // https://github.com/ariya/phantomjs/issues/12332 + return super.getBrowsersExcludingPhantomJS(); + } + + @Test + public void testThemeChange() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + + int reindeerHeight = grid.getRow(0).getSize().getHeight(); + + grid.getCell(0, 0).click(); + + int valoHeight = grid.getRow(0).getSize().getHeight(); + + Assert.assertTrue( + "Row height should increase when changing from Reindeer to Valo", + valoHeight > reindeerHeight); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridUndefinedObjectConverter.java b/uitest/src/com/vaadin/tests/components/grid/GridUndefinedObjectConverter.java new file mode 100644 index 0000000000..fba2bbf698 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridUndefinedObjectConverter.java @@ -0,0 +1,37 @@ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; + +public class GridUndefinedObjectConverter extends AbstractTestUI { + private static class Pojo { + private final String content; + + public Pojo(String content) { + this.content = content; + } + + @Override + public String toString() { + return "Pojo:" + content; + } + } + + @Override + @SuppressWarnings("all") + protected void setup(VaadinRequest request) { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty("pojo", Pojo.class, new Pojo("foo")); + container.addContainerProperty("pojo object ", Object.class, new Pojo( + "bar")); + container.addContainerProperty("int", Integer.class, 1); + container.addContainerProperty("int object", Object.class, 2); + container.addContainerProperty("string", String.class, "foo"); + container.addContainerProperty("string object", Object.class, "bar"); + container.addItem(); + + addComponent(new Grid(container)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridUndefinedObjectConverterTest.java b/uitest/src/com/vaadin/tests/components/grid/GridUndefinedObjectConverterTest.java new file mode 100644 index 0000000000..401bfda885 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridUndefinedObjectConverterTest.java @@ -0,0 +1,25 @@ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridUndefinedObjectConverterTest extends MultiBrowserTest { + @Test + public void testDefaultToStringRendering() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + assertEquals("pojo", "Pojo:foo", grid.getCell(0, 0).getText()); + assertEquals("pojo object", "Pojo:bar", grid.getCell(0, 1).getText()); + assertEquals("int", "1", grid.getCell(0, 2).getText()); + assertEquals("int object", "2", grid.getCell(0, 3).getText()); + assertEquals("string", "foo", grid.getCell(0, 4).getText()); + assertEquals("string object", "bar", grid.getCell(0, 5).getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridWithoutRenderer.java b/uitest/src/com/vaadin/tests/components/grid/GridWithoutRenderer.java new file mode 100644 index 0000000000..fd5e6fdc01 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridWithoutRenderer.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.util.PersonContainer; +import com.vaadin.ui.Grid; + +@Theme("valo") +public class GridWithoutRenderer extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(); + grid.setContainerDataSource(PersonContainer.createWithTestData()); + addComponent(grid); + + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java b/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java new file mode 100644 index 0000000000..5d6ffbd8a7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridWithoutRendererTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.SingleBrowserTest; + +@TestCategory("grid") +public class GridWithoutRendererTest extends SingleBrowserTest { + + @Test + public void ensureNoError() { + openTestURL(); + // WebElement errorIndicator = findElement(By + // .cssSelector("v-error-indicator")); + // System.out.println(errorIndicator); + List<WebElement> errorIndicator = findElements(By + .xpath("//span[@class='v-errorindicator']")); + Assert.assertTrue("There should not be an error indicator", + errorIndicator.isEmpty()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumns.java b/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumns.java new file mode 100644 index 0000000000..b6da30d314 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumns.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; + +public class InitialFrozenColumns extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(); + grid.setSelectionMode(SelectionMode.NONE); + + grid.addColumn("foo").setWidth(200); + grid.addColumn("bar").setWidth(200); + grid.addColumn("baz").setWidth(200); + + grid.addRow("a", "b", "c"); + + grid.setFrozenColumnCount(2); + + addComponent(grid); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java b/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java new file mode 100644 index 0000000000..7a6d37d089 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/InitialFrozenColumnsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertTrue; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class InitialFrozenColumnsTest extends MultiBrowserTest { + @Test + public void testInitialFrozenColumns() { + setDebug(true); + openTestURL(); + + Assert.assertFalse("Notification was present", + isElementPresent(NotificationElement.class)); + + WebElement cell = $(GridElement.class).first().getCell(0, 0); + assertTrue(cell.getAttribute("class").contains("frozen")); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java b/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java new file mode 100644 index 0000000000..ce15676b60 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/IntArrayRenderer.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.ui.Grid.AbstractRenderer; + +public class IntArrayRenderer extends AbstractRenderer<int[]> { + public IntArrayRenderer() { + super(int[].class); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderers.java b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderers.java new file mode 100644 index 0000000000..4bfa244c22 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderers.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; + +public class JavaScriptRenderers extends AbstractTestUI { + + public static class MyBean { + private int integer; + private String string; + + public MyBean(int integer, String string) { + super(); + this.integer = integer; + this.string = string; + } + + public int getInteger() { + return integer; + } + + public void setInteger(int integer) { + this.integer = integer; + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + } + + @Override + protected void setup(VaadinRequest request) { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty("id", Integer.class, Integer.valueOf(0)); + container.addContainerProperty("bean", MyBean.class, null); + + for (int i = 0; i < 1000; i++) { + Integer itemId = Integer.valueOf(i); + Item item = container.addItem(itemId); + item.getItemProperty("id").setValue(itemId); + item.getItemProperty("bean").setValue( + new MyBean(i + 1, Integer.toString(i - 1))); + } + + Grid grid = new Grid(container); + + grid.getColumn("bean").setRenderer(new MyBeanJSRenderer()); + grid.getColumn("bean").setWidth(250); + + addComponent(grid); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java new file mode 100644 index 0000000000..96fd672ab1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/JavaScriptRenderersTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class JavaScriptRenderersTest extends MultiBrowserTest { + + @Test + public void testJavaScriptRenderer() { + setDebug(true); + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + GridCellElement cell_1_1 = grid.getCell(1, 1); + + // Verify render functionality + Assert.assertEquals("Bean(2, 0)", cell_1_1.getText()); + + // Verify init functionality + Assert.assertEquals("1", cell_1_1.getAttribute("column")); + + // Verify onbrowserevent + cell_1_1.click(); + Assert.assertTrue(cell_1_1.getText().startsWith( + "Clicked 1 with key 1 at")); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/MyBeanJSRenderer.java b/uitest/src/com/vaadin/tests/components/grid/MyBeanJSRenderer.java new file mode 100644 index 0000000000..ccb94f5d2d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/MyBeanJSRenderer.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.JavaScript; +import com.vaadin.tests.components.grid.JavaScriptRenderers.MyBean; +import com.vaadin.ui.renderer.AbstractJavaScriptRenderer; + +/** + * + * @since + * @author Vaadin Ltd + */ +@JavaScript("myBeanJsRenderer.js") +public class MyBeanJSRenderer extends AbstractJavaScriptRenderer<MyBean> { + + public MyBeanJSRenderer() { + super(MyBean.class); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java b/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java new file mode 100644 index 0000000000..7b3390a7e7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/RowAwareRenderer.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.tests.widgetset.client.grid.RowAwareRendererConnector.RowAwareRendererRpc; +import com.vaadin.ui.Grid.AbstractRenderer; +import com.vaadin.ui.Label; + +public class RowAwareRenderer extends AbstractRenderer<Void> { + public RowAwareRenderer(final Label debugLabel) { + super(Void.class); + registerRpc(new RowAwareRendererRpc() { + @Override + public void clicky(String key) { + Object itemId = getItemId(key); + debugLabel.setValue("key: " + key + ", itemId: " + itemId); + } + }); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/SelectDuringInit.java b/uitest/src/com/vaadin/tests/components/grid/SelectDuringInit.java new file mode 100644 index 0000000000..d8394acd19 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/SelectDuringInit.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; + +public class SelectDuringInit extends AbstractTestUI { + + @Override + protected void setup(VaadinRequest request) { + Grid grid = new Grid(); + grid.setSelectionMode(SelectionMode.MULTI); + + grid.addColumn("value"); + grid.addRow("row 1"); + grid.addRow("row 2"); + grid.addRow("row 3"); + + grid.select(Integer.valueOf(2)); + + addComponent(grid); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/SelectDuringInitTest.java b/uitest/src/com/vaadin/tests/components/grid/SelectDuringInitTest.java new file mode 100644 index 0000000000..edfc8031a8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/SelectDuringInitTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.tb3.SingleBrowserTest; + +public class SelectDuringInitTest extends SingleBrowserTest { + + @Test + public void testSelectDuringInit() { + openTestURL(); + + GridElement grid = $(GridElement.class).first(); + + Assert.assertTrue(grid.getRow(1).isSelected()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/WidgetRenderers.java b/uitest/src/com/vaadin/tests/components/grid/WidgetRenderers.java new file mode 100644 index 0000000000..0d51558cd1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/WidgetRenderers.java @@ -0,0 +1,117 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.Resource; +import com.vaadin.server.ThemeResource; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.renderer.ButtonRenderer; +import com.vaadin.ui.renderer.ClickableRenderer.RendererClickEvent; +import com.vaadin.ui.renderer.ClickableRenderer.RendererClickListener; +import com.vaadin.ui.renderer.ImageRenderer; +import com.vaadin.ui.renderer.ProgressBarRenderer; + +@SuppressWarnings("all") +public class WidgetRenderers extends AbstractTestUI { + + static final String PROPERTY_ID = "property id"; + + @Override + protected void setup(VaadinRequest request) { + IndexedContainer container = new IndexedContainer(); + + container.addContainerProperty(ProgressBarRenderer.class, Double.class, + null); + container + .addContainerProperty(ButtonRenderer.class, String.class, null); + container.addContainerProperty(ImageRenderer.class, Resource.class, + null); + container.addContainerProperty(PROPERTY_ID, String.class, null); + + final Item item = container.getItem(container.addItem()); + + item.getItemProperty(ProgressBarRenderer.class).setValue(0.3); + item.getItemProperty(ButtonRenderer.class).setValue("Click"); + item.getItemProperty(ImageRenderer.class).setValue( + new ThemeResource("window/img/close.png")); + item.getItemProperty(PROPERTY_ID).setValue("Click"); + + final Grid grid = new Grid(container); + + grid.setId("test-grid"); + grid.setSelectionMode(SelectionMode.NONE); + + grid.getColumn(ProgressBarRenderer.class).setRenderer( + new ProgressBarRenderer()); + + grid.getColumn(ButtonRenderer.class).setRenderer( + new ButtonRenderer(new RendererClickListener() { + @Override + public void click(RendererClickEvent event) { + item.getItemProperty(ButtonRenderer.class).setValue( + "Clicked!"); + } + })); + + grid.getColumn(ImageRenderer.class).setRenderer( + new ImageRenderer(new RendererClickListener() { + + @Override + public void click(RendererClickEvent event) { + item.getItemProperty(ImageRenderer.class).setValue( + new ThemeResource("window/img/maximize.png")); + } + })); + + grid.getColumn(PROPERTY_ID).setRenderer( + new ButtonRenderer(new RendererClickListener() { + @Override + public void click(RendererClickEvent event) { + item.getItemProperty(PROPERTY_ID).setValue( + event.getPropertyId()); + } + })); + + addComponent(grid); + + addComponent(new NativeButton("Change column order", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + grid.setColumnOrder(ImageRenderer.class, + ProgressBarRenderer.class, ButtonRenderer.class); + } + })); + } + + @Override + protected String getTestDescription() { + return "Tests the functionality of widget-based renderers"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(13334); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java b/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java new file mode 100644 index 0000000000..5da92b2034 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/WidgetRenderersTest.java @@ -0,0 +1,132 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +/** + * TB tests for the various builtin widget-based renderers. + * + * @since + * @author Vaadin Ltd + */ +@TestCategory("grid") +public class WidgetRenderersTest extends MultiBrowserTest { + + @Test + public void testProgressBarRenderer() { + openTestURL(); + + assertTrue(getGridCell(0, 0).isElementPresent( + By.className("v-progressbar"))); + } + + @Test + public void testButtonRenderer() { + openTestURL(); + + WebElement button = getGridCell(0, 1).findElement( + By.className("v-nativebutton")); + + button.click(); + + assertEquals("Clicked!", button.getText()); + } + + @Test + public void testButtonRendererAfterCellBeingFocused() { + openTestURL(); + + GridCellElement buttonCell = getGridCell(0, 1); + assertFalse("cell should not be focused before focusing", + buttonCell.isFocused()); + + // avoid clicking on the button + buttonCell.click(buttonCell.getSize().getWidth() - 10, 5); + assertTrue("cell should be focused after focusing", + buttonCell.isFocused()); + + WebElement button = buttonCell.findElement(By + .className("v-nativebutton")); + assertNotEquals("Button should not be clicked before click", + "Clicked!", button.getText()); + + new Actions(getDriver()).moveToElement(button).click().perform(); + assertEquals("Button should be clicked after click", "Clicked!", + button.getText()); + } + + @Test + public void testImageRenderer() { + openTestURL(); + + WebElement image = getGridCell(0, 2).findElement( + By.className("gwt-Image")); + + assertTrue(image.getAttribute("src").endsWith("window/img/close.png")); + + image.click(); + + assertTrue(image.getAttribute("src") + .endsWith("window/img/maximize.png")); + } + + @Test + public void testColumnReorder() { + setDebug(true); + openTestURL(); + + $(ButtonElement.class).caption("Change column order").first().click(); + + assertFalse("Notification was present", + isElementPresent(NotificationElement.class)); + + assertTrue(getGridCell(0, 0) + .isElementPresent(By.className("gwt-Image"))); + assertTrue(getGridCell(0, 1).isElementPresent( + By.className("v-progressbar"))); + assertTrue(getGridCell(0, 2).isElementPresent( + By.className("v-nativebutton"))); + } + + @Test + public void testPropertyIdInEvent() { + openTestURL(); + WebElement button = getGridCell(0, 3).findElement( + By.className("v-nativebutton")); + button.click(); + assertEquals(WidgetRenderers.PROPERTY_ID, button.getText()); + } + + GridCellElement getGridCell(int row, int col) { + return $(GridElement.class).first().getCell(row, col); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeatures.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeatures.java new file mode 100644 index 0000000000..8e1a80a830 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeatures.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Title; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.EscalatorBasicClientFeaturesWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; +import com.vaadin.ui.UI; + +@Widgetset(TestingWidgetSet.NAME) +@Title("Escalator basic client features") +public class EscalatorBasicClientFeatures extends UI { + + @Override + public void init(VaadinRequest request) { + setContent(new TestWidgetComponent( + EscalatorBasicClientFeaturesWidget.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java new file mode 100644 index 0000000000..92c7f3e6a6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorBasicClientFeaturesTest.java @@ -0,0 +1,262 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("escalator") +public abstract class EscalatorBasicClientFeaturesTest extends MultiBrowserTest { + protected static final String COLUMNS_AND_ROWS = "Columns and Rows"; + + protected static final String COLUMNS = "Columns"; + protected static final String ADD_ONE_COLUMN_TO_BEGINNING = "Add one column to beginning"; + protected static final String ADD_ONE_ROW_TO_BEGINNING = "Add one row to beginning"; + protected static final String REMOVE_ONE_COLUMN_FROM_BEGINNING = "Remove one column from beginning"; + protected static final String REMOVE_ONE_ROW_FROM_BEGINNING = "Remove one row from beginning"; + protected static final String REMOVE_50_ROWS_FROM_BOTTOM = "Remove 50 rows from bottom"; + protected static final String REMOVE_50_ROWS_FROM_ALMOST_BOTTOM = "Remove 50 rows from almost bottom"; + protected static final String ADD_ONE_OF_EACH_ROW = "Add one of each row"; + protected static final String RESIZE_FIRST_COLUMN_TO_MAX_WIDTH = "Resize first column to max width"; + protected static final String RESIZE_FIRST_COLUMN_TO_100PX = "Resize first column to 100 px"; + + protected static final String HEADER_ROWS = "Header Rows"; + protected static final String BODY_ROWS = "Body Rows"; + protected static final String FOOTER_ROWS = "Footer Rows"; + + protected static final String REMOVE_ALL_INSERT_SCROLL = "Remove all, insert 30 and scroll 40px"; + + protected static final String GENERAL = "General"; + protected static final String DETACH_ESCALATOR = "Detach Escalator"; + protected static final String POPULATE_COLUMN_ROW = "Populate Escalator (columns, then rows)"; + protected static final String POPULATE_ROW_COLUMN = "Populate Escalator (rows, then columns)"; + protected static final String CLEAR_COLUMN_ROW = "Clear (columns, then rows)"; + protected static final String CLEAR_ROW_COLUMN = "Clear (rows, then columns)"; + + protected static final String FEATURES = "Features"; + protected static final String FROZEN_COLUMNS = "Frozen columns"; + protected static final String FREEZE_1_COLUMN = "Freeze 1 column"; + protected static final String FREEZE_0_COLUMNS = "Freeze 0 columns"; + protected static final String COLUMN_SPANNING = "Column spanning"; + protected static final String COLSPAN_NORMAL = "Apply normal colspan"; + protected static final String COLSPAN_NONE = "Apply no colspan"; + + @Override + protected Class<?> getUIClass() { + return EscalatorBasicClientFeatures.class; + } + + protected TestBenchElement getEscalator() { + By className = By.className("v-escalator"); + if (isElementPresent(className)) { + return (TestBenchElement) findElement(className); + } + return null; + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + protected TestBenchElement getHeaderRow(int row) { + return getRow("thead", row); + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + protected TestBenchElement getBodyRow(int row) { + return getRow("tbody", row); + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + protected TestBenchElement getFooterRow(int row) { + return getRow("tfoot", row); + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + protected TestBenchElement getHeaderCell(int row, int col) { + return getCell("thead", row, col); + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + protected TestBenchElement getBodyCell(int row, int col) { + return getCell("tbody", row, col); + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + protected TestBenchElement getFooterCell(int row, int col) { + return getCell("tfoot", row, col); + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + private TestBenchElement getCell(String sectionTag, int row, int col) { + TestBenchElement rowElement = getRow(sectionTag, row); + By xpath = By.xpath("*[" + (col + 1) + "]"); + if (rowElement != null && rowElement.isElementPresent(xpath)) { + return (TestBenchElement) rowElement.findElement(xpath); + } + return null; + } + + /** + * @param row + * the index of the row element in the section. If negative, the + * calculation starts from the end (-1 is the last, -2 is the + * second-to-last etc) + */ + private TestBenchElement getRow(String sectionTag, int row) { + TestBenchElement escalator = getEscalator(); + WebElement tableSection = escalator.findElement(By.tagName(sectionTag)); + By xpath; + + if (row >= 0) { + int fromFirst = row + 1; + xpath = By.xpath("tr[" + fromFirst + "]"); + } else { + int fromLast = Math.abs(row + 1); + xpath = By.xpath("tr[last() - " + fromLast + "]"); + } + if (tableSection != null + && ((TestBenchElement) tableSection).isElementPresent(xpath)) { + return (TestBenchElement) tableSection.findElement(xpath); + } + return null; + } + + protected void selectMenu(String menuCaption) { + TestBenchElement menuElement = getMenuElement(menuCaption); + Dimension size = menuElement.getSize(); + new Actions(getDriver()).moveToElement(menuElement, size.width - 10, + size.height / 2).perform(); + } + + private TestBenchElement getMenuElement(String menuCaption) { + return (TestBenchElement) findElement(By.xpath("//td[text() = '" + + menuCaption + "']")); + } + + protected void selectMenuPath(String... menuCaptions) { + new Actions(getDriver()).moveToElement(getMenuElement(menuCaptions[0])) + .click().perform(); + for (int i = 1; i < menuCaptions.length - 1; ++i) { + selectMenu(menuCaptions[i]); + new Actions(getDriver()).moveByOffset(20, 0).perform(); + } + new Actions(getDriver()) + .moveToElement( + getMenuElement(menuCaptions[menuCaptions.length - 1])) + .click().perform(); + } + + protected void assertLogContains(String substring) { + assertTrue("log should've contained, but didn't: " + substring, + getLogText().contains(substring)); + } + + protected void assertLogDoesNotContain(String substring) { + assertFalse("log shouldn't have contained, but did: " + substring, + getLogText().contains(substring)); + } + + private String getLogText() { + WebElement log = findElement(By.cssSelector("#log")); + return log.getText(); + } + + protected void assertLogContainsInOrder(String... substrings) { + String log = getLogText(); + int cursor = 0; + for (String substring : substrings) { + String remainingLog = log.substring(cursor, log.length()); + int substringIndex = remainingLog.indexOf(substring); + if (substringIndex == -1) { + fail("substring \"" + substring + + "\" was not found in order from log."); + } + + cursor += substringIndex + substring.length(); + } + } + + protected void scrollVerticallyTo(int px) { + executeScript("arguments[0].scrollTop = " + px, getVeticalScrollbar()); + } + + private TestBenchElement getVeticalScrollbar() { + return (TestBenchElement) getEscalator().findElement( + By.className("v-escalator-scroller-vertical")); + } + + protected void scrollHorizontallyTo(int px) { + executeScript("arguments[0].scrollLeft = " + px, + getHorizontalScrollbar()); + } + + private TestBenchElement getHorizontalScrollbar() { + return (TestBenchElement) getEscalator().findElement( + By.className("v-escalator-scroller-horizontal")); + } + + protected Object executeScript(String script, Object... args) { + return ((JavascriptExecutor) getDriver()).executeScript(script, args); + } + + protected void populate() { + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorUpdaterUi.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorUpdaterUi.java new file mode 100644 index 0000000000..ef997b3cae --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/EscalatorUpdaterUi.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.EscalatorBasicClientFeaturesWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; +import com.vaadin.ui.UI; + +@Widgetset(TestingWidgetSet.NAME) +public class EscalatorUpdaterUi extends UI { + + @Override + protected void init(VaadinRequest request) { + setContent(new TestWidgetComponent( + EscalatorBasicClientFeaturesWidget.UpdaterLifetimeWidget.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeatures.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeatures.java new file mode 100644 index 0000000000..429f15bb47 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeatures.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridBasicClientFeaturesWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; +import com.vaadin.ui.UI; + +/** + * Initializer shell for GridClientBasicFeatures test application + * + * @since + * @author Vaadin Ltd + */ +@Widgetset(TestingWidgetSet.NAME) +public class GridBasicClientFeatures extends UI { + + @Override + protected void init(VaadinRequest request) { + setContent(new TestWidgetComponent(GridBasicClientFeaturesWidget.class)); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java new file mode 100644 index 0000000000..d0e076fd3b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicClientFeaturesTest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import org.openqa.selenium.Dimension; +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.elements.GridElement; + +/** + * Variant of GridBasicFeaturesTest to be used with GridBasicClientFeatures. + * + * @since + * @author Vaadin Ltd + */ +public abstract class GridBasicClientFeaturesTest extends GridBasicFeaturesTest { + + private boolean composite = false; + + @Override + protected Class<?> getUIClass() { + return GridBasicClientFeatures.class; + } + + @Override + protected String getDeploymentPath() { + String path = super.getDeploymentPath(); + if (composite) { + path += (path.contains("?") ? "&" : "?") + "composite"; + } + return path; + } + + protected void setUseComposite(boolean useComposite) { + composite = useComposite; + } + + @Override + protected void selectMenu(String menuCaption) { + WebElement menuElement = getMenuElement(menuCaption); + Dimension size = menuElement.getSize(); + new Actions(getDriver()).moveToElement(menuElement, size.width - 10, + size.height / 2).perform(); + } + + private WebElement getMenuElement(String menuCaption) { + return getDriver().findElement( + By.xpath("//td[text() = '" + menuCaption + "']")); + } + + @Override + protected void selectMenuPath(String... menuCaptions) { + new Actions(getDriver()).moveToElement(getMenuElement(menuCaptions[0])) + .click().perform(); + for (int i = 1; i < menuCaptions.length - 1; ++i) { + selectMenu(menuCaptions[i]); + new Actions(getDriver()).moveByOffset(20, 0).perform(); + } + new Actions(getDriver()) + .moveToElement( + getMenuElement(menuCaptions[menuCaptions.length - 1])) + .click().perform(); + } + + @Override + protected GridElement getGridElement() { + if (composite) { + // Composite requires the basic client features widget for subparts + return ((TestBenchElement) findElement(By + .vaadin("//TestWidgetComponent"))) + .wrap(GridElement.class); + } else { + return super.getGridElement(); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java new file mode 100644 index 0000000000..7a625e2f25 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeatures.java @@ -0,0 +1,1026 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Random; + +import com.vaadin.data.Container.Filter; +import com.vaadin.data.Item; +import com.vaadin.data.Property; +import com.vaadin.data.fieldgroup.FieldGroup.CommitException; +import com.vaadin.data.sort.Sort; +import com.vaadin.data.sort.SortOrder; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.ItemClickEvent; +import com.vaadin.event.ItemClickEvent.ItemClickListener; +import com.vaadin.event.SelectionEvent; +import com.vaadin.event.SelectionEvent.SelectionListener; +import com.vaadin.event.SortEvent; +import com.vaadin.event.SortEvent.SortListener; +import com.vaadin.shared.data.sort.SortDirection; +import com.vaadin.shared.ui.grid.GridStaticCellType; +import com.vaadin.shared.ui.grid.HeightMode; +import com.vaadin.tests.components.AbstractComponentTest; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Grid.CellReference; +import com.vaadin.ui.Grid.CellStyleGenerator; +import com.vaadin.ui.Grid.Column; +import com.vaadin.ui.Grid.FooterCell; +import com.vaadin.ui.Grid.HeaderCell; +import com.vaadin.ui.Grid.HeaderRow; +import com.vaadin.ui.Grid.MultiSelectionModel; +import com.vaadin.ui.Grid.RowReference; +import com.vaadin.ui.Grid.RowStyleGenerator; +import com.vaadin.ui.Grid.SelectionMode; +import com.vaadin.ui.renderer.DateRenderer; +import com.vaadin.ui.renderer.HtmlRenderer; +import com.vaadin.ui.renderer.NumberRenderer; + +/** + * Tests the basic features like columns, footers and headers + * + * @since + * @author Vaadin Ltd + */ +public class GridBasicFeatures extends AbstractComponentTest<Grid> { + + public static final String ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4 = "Row numbers for 3/4"; + public static final String ROW_STYLE_GENERATOR_NONE = "None"; + public static final String ROW_STYLE_GENERATOR_ROW_NUMBERS = "Row numbers"; + public static final String CELL_STYLE_GENERATOR_NONE = "None"; + public static final String CELL_STYLE_GENERATOR_PROPERTY_TO_STRING = "Property to string"; + public static final String CELL_STYLE_GENERATOR_SPECIAL = "Special for 1/4 Column 1"; + private static final int MANUALLY_FORMATTED_COLUMNS = 5; + public static final int COLUMNS = 12; + public static final int ROWS = 1000; + + private int containerDelay = 0; + + private IndexedContainer ds; + private Grid grid; + private SelectionListener selectionListener = new SelectionListener() { + + @Override + public void select(SelectionEvent event) { + Iterator<Object> iter = event.getAdded().iterator(); + Object addedRow = (iter.hasNext() ? iter.next() : "none"); + iter = event.getRemoved().iterator(); + Object removedRow = (iter.hasNext() ? iter.next() : "none"); + log("SelectionEvent: Added " + addedRow + ", Removed " + removedRow); + } + }; + + private ItemClickListener itemClickListener = new ItemClickListener() { + + @Override + public void itemClick(ItemClickEvent event) { + log("Item " + (event.isDoubleClick() ? "double " : "") + + "click on " + event.getPropertyId() + ", item " + + event.getItemId()); + } + }; + + @Override + @SuppressWarnings("unchecked") + protected Grid constructComponent() { + + // Build data source + ds = new IndexedContainer() { + @Override + public List<Object> getItemIds(int startIndex, int numberOfIds) { + log("Requested items " + startIndex + " - " + + (startIndex + numberOfIds)); + if (containerDelay > 0) { + try { + Thread.sleep(containerDelay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return super.getItemIds(startIndex, numberOfIds); + } + }; + + { + int col = 0; + for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; col++) { + ds.addContainerProperty(getColumnProperty(col), String.class, + ""); + } + + ds.addContainerProperty(getColumnProperty(col++), Integer.class, + Integer.valueOf(0)); + ds.addContainerProperty(getColumnProperty(col++), Date.class, + new Date()); + ds.addContainerProperty(getColumnProperty(col++), String.class, ""); + + // Random numbers + ds.addContainerProperty(getColumnProperty(col++), Integer.class, 0); + ds.addContainerProperty(getColumnProperty(col++), Integer.class, 0); + + } + + { + Random rand = new Random(); + rand.setSeed(13334); + long timestamp = 0; + for (int row = 0; row < ROWS; row++) { + Item item = ds.addItem(Integer.valueOf(row)); + int col = 0; + for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; col++) { + item.getItemProperty(getColumnProperty(col)).setValue( + "(" + row + ", " + col + ")"); + } + item.getItemProperty(getColumnProperty(1)).setReadOnly(true); + + item.getItemProperty(getColumnProperty(col++)).setValue( + Integer.valueOf(row)); + item.getItemProperty(getColumnProperty(col++)).setValue( + new Date(timestamp)); + timestamp += 91250000; // a bit over a day, just to get + // variation + item.getItemProperty(getColumnProperty(col++)).setValue( + "<b>" + row + "</b>"); + + // Random numbers + item.getItemProperty(getColumnProperty(col++)).setValue( + rand.nextInt()); + // Random between 0 - 5 to test multisorting + item.getItemProperty(getColumnProperty(col++)).setValue( + rand.nextInt(5)); + } + } + + // Create grid + Grid grid = new Grid(ds); + + { + int col = grid.getContainerDataSource().getContainerPropertyIds() + .size() + - MANUALLY_FORMATTED_COLUMNS; + grid.getColumn(getColumnProperty(col++)).setRenderer( + new NumberRenderer(new DecimalFormat("0,000.00", + DecimalFormatSymbols.getInstance(new Locale("fi", + "FI"))))); + grid.getColumn(getColumnProperty(col++)).setRenderer( + new DateRenderer(new SimpleDateFormat("dd.MM.yy HH:mm"))); + grid.getColumn(getColumnProperty(col++)).setRenderer( + new HtmlRenderer()); + grid.getColumn(getColumnProperty(col++)).setRenderer( + new NumberRenderer()); + grid.getColumn(getColumnProperty(col++)).setRenderer( + new NumberRenderer()); + } + + // Create footer + grid.appendFooterRow(); + grid.setFooterVisible(false); + + // Add footer values (header values are automatically created) + for (int col = 0; col < COLUMNS; col++) { + grid.getFooterRow(0).getCell(getColumnProperty(col)) + .setText("Footer " + col); + } + + // Set varying column widths + for (int col = 0; col < COLUMNS; col++) { + grid.getColumn(getColumnProperty(col)).setWidth(100 + col * 50); + } + + grid.addSortListener(new SortListener() { + @Override + public void sort(SortEvent event) { + + log("SortOrderChangeEvent: isUserOriginated? " + + event.isUserOriginated()); + } + }); + + grid.setSelectionMode(SelectionMode.NONE); + + grid.getEditorField(getColumnProperty(3)).setReadOnly(true); + + createGridActions(); + + createColumnActions(); + + createPropertyActions(); + + createHeaderActions(); + + createFooterActions(); + + createRowActions(); + + createEditorActions(); + + addHeightActions(); + + addFilterActions(); + + this.grid = grid; + return grid; + } + + private void addFilterActions() { + createClickAction("Column 1 starts with \"(23\"", "Filter", + new Command<Grid, Void>() { + @Override + public void execute(Grid grid, Void value, Object data) { + ds.addContainerFilter(new Filter() { + + @Override + public boolean passesFilter(Object itemId, Item item) + throws UnsupportedOperationException { + return item.getItemProperty("Column 1") + .getValue().toString() + .startsWith("(23"); + } + + @Override + public boolean appliesToProperty(Object propertyId) { + return propertyId.equals("Column 1"); + } + }); + } + }, null); + + createClickAction("Add impassable filter", "Filter", + new Command<Grid, Void>() { + @Override + public void execute(Grid c, Void value, Object data) { + ds.addContainerFilter(new Filter() { + @Override + public boolean passesFilter(Object itemId, Item item) + throws UnsupportedOperationException { + return false; + } + + @Override + public boolean appliesToProperty(Object propertyId) { + return true; + } + }); + } + }, null); + } + + protected void createGridActions() { + LinkedHashMap<String, String> primaryStyleNames = new LinkedHashMap<String, String>(); + primaryStyleNames.put("v-grid", "v-grid"); + primaryStyleNames.put("v-escalator", "v-escalator"); + primaryStyleNames.put("my-grid", "my-grid"); + + createMultiClickAction("Primary style name", "State", + primaryStyleNames, new Command<Grid, String>() { + + @Override + public void execute(Grid grid, String value, Object data) { + grid.setPrimaryStyleName(value); + + } + }, primaryStyleNames.get("v-grid")); + + LinkedHashMap<String, SelectionMode> selectionModes = new LinkedHashMap<String, Grid.SelectionMode>(); + selectionModes.put("single", SelectionMode.SINGLE); + selectionModes.put("multi", SelectionMode.MULTI); + selectionModes.put("none", SelectionMode.NONE); + createSelectAction("Selection mode", "State", selectionModes, "none", + new Command<Grid, Grid.SelectionMode>() { + @Override + public void execute(Grid grid, SelectionMode selectionMode, + Object data) { + grid.setSelectionMode(selectionMode); + if (selectionMode == SelectionMode.SINGLE) { + grid.addSelectionListener(selectionListener); + } else { + grid.removeSelectionListener(selectionListener); + } + } + }); + + LinkedHashMap<String, Integer> selectionLimits = new LinkedHashMap<String, Integer>(); + selectionLimits.put("2", Integer.valueOf(2)); + selectionLimits.put("1000", Integer.valueOf(1000)); + selectionLimits.put("Integer.MAX_VALUE", + Integer.valueOf(Integer.MAX_VALUE)); + createSelectAction("Selection limit", "State", selectionLimits, "1000", + new Command<Grid, Integer>() { + @Override + public void execute(Grid grid, Integer limit, Object data) { + if (!(grid.getSelectionModel() instanceof MultiSelectionModel)) { + grid.setSelectionMode(SelectionMode.MULTI); + } + + ((MultiSelectionModel) grid.getSelectionModel()) + .setSelectionLimit(limit.intValue()); + } + }); + + LinkedHashMap<String, List<SortOrder>> sortableProperties = new LinkedHashMap<String, List<SortOrder>>(); + for (Object propertyId : ds.getSortableContainerPropertyIds()) { + sortableProperties.put(propertyId + ", ASC", Sort.by(propertyId) + .build()); + sortableProperties.put(propertyId + ", DESC", + Sort.by(propertyId, SortDirection.DESCENDING).build()); + } + createSelectAction("Sort by column", "State", sortableProperties, + "Column 9, ascending", new Command<Grid, List<SortOrder>>() { + @Override + public void execute(Grid grid, List<SortOrder> sortOrder, + Object data) { + grid.setSortOrder(sortOrder); + } + }); + + createBooleanAction("Reverse Grid Columns", "State", false, + new Command<Grid, Boolean>() { + + @Override + public void execute(Grid c, Boolean value, Object data) { + List<Object> ids = new ArrayList<Object>(); + ids.addAll(ds.getContainerPropertyIds()); + if (!value) { + c.setColumnOrder(ids.toArray()); + } else { + Object[] idsArray = new Object[ids.size()]; + for (int i = 0; i < ids.size(); ++i) { + idsArray[i] = ids.get((ids.size() - 1) - i); + } + c.setColumnOrder(idsArray); + } + } + }); + + LinkedHashMap<String, CellStyleGenerator> cellStyleGenerators = new LinkedHashMap<String, CellStyleGenerator>(); + LinkedHashMap<String, RowStyleGenerator> rowStyleGenerators = new LinkedHashMap<String, RowStyleGenerator>(); + rowStyleGenerators.put(ROW_STYLE_GENERATOR_NONE, null); + rowStyleGenerators.put(ROW_STYLE_GENERATOR_ROW_NUMBERS, + new RowStyleGenerator() { + @Override + public String getStyle(RowReference rowReference) { + return "row" + rowReference.getItemId(); + } + }); + rowStyleGenerators.put(ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4, + new RowStyleGenerator() { + @Override + public String getStyle(RowReference rowReference) { + int rowIndex = ((Integer) rowReference.getItemId()) + .intValue(); + + if (rowIndex % 4 == 0) { + return null; + } else { + return "row" + rowReference.getItemId(); + } + } + }); + cellStyleGenerators.put(CELL_STYLE_GENERATOR_NONE, null); + cellStyleGenerators.put(CELL_STYLE_GENERATOR_PROPERTY_TO_STRING, + new CellStyleGenerator() { + @Override + public String getStyle(CellReference cellReference) { + return cellReference.getPropertyId().toString() + .replace(' ', '-'); + } + }); + cellStyleGenerators.put(CELL_STYLE_GENERATOR_SPECIAL, + new CellStyleGenerator() { + @Override + public String getStyle(CellReference cellReference) { + int rowIndex = ((Integer) cellReference.getItemId()) + .intValue(); + Object propertyId = cellReference.getPropertyId(); + if (rowIndex % 4 == 1) { + return null; + } else if (rowIndex % 4 == 3 + && "Column 1".equals(propertyId)) { + return null; + } + return propertyId.toString().replace(' ', '_'); + } + }); + + createSelectAction("Row style generator", "State", rowStyleGenerators, + CELL_STYLE_GENERATOR_NONE, + new Command<Grid, RowStyleGenerator>() { + @Override + public void execute(Grid grid, RowStyleGenerator generator, + Object data) { + grid.setRowStyleGenerator(generator); + } + }); + + createSelectAction("Cell style generator", "State", + cellStyleGenerators, CELL_STYLE_GENERATOR_NONE, + new Command<Grid, CellStyleGenerator>() { + @Override + public void execute(Grid grid, + CellStyleGenerator generator, Object data) { + grid.setCellStyleGenerator(generator); + } + }); + + LinkedHashMap<String, Integer> frozenOptions = new LinkedHashMap<String, Integer>(); + for (int i = -1; i <= COLUMNS; i++) { + frozenOptions.put(String.valueOf(i), Integer.valueOf(i)); + } + createSelectAction("Frozen column count", "State", frozenOptions, "0", + new Command<Grid, Integer>() { + @Override + public void execute(Grid c, Integer value, Object data) { + c.setFrozenColumnCount(value.intValue()); + } + }); + + LinkedHashMap<String, Integer> containerDelayValues = new LinkedHashMap<String, Integer>(); + for (int delay : new int[] { 0, 500, 2000, 10000 }) { + containerDelayValues.put(String.valueOf(delay), + Integer.valueOf(delay)); + } + + createSelectAction("Container delay", "State", containerDelayValues, + "0", new Command<Grid, Integer>() { + @Override + public void execute(Grid grid, Integer delay, Object data) { + containerDelay = delay.intValue(); + } + }); + + createBooleanAction("ItemClickListener", "State", false, + new Command<Grid, Boolean>() { + + @Override + public void execute(Grid c, Boolean value, Object data) { + if (!value) { + c.removeItemClickListener(itemClickListener); + } else { + c.addItemClickListener(itemClickListener); + } + } + + }); + } + + protected void createHeaderActions() { + createCategory("Header", null); + + createBooleanAction("Visible", "Header", true, + new Command<Grid, Boolean>() { + + @Override + public void execute(Grid grid, Boolean value, Object data) { + grid.setHeaderVisible(value); + } + }); + + LinkedHashMap<String, String> defaultRows = new LinkedHashMap<String, String>(); + defaultRows.put("Top", "Top"); + defaultRows.put("Bottom", "Bottom"); + defaultRows.put("Unset", "Unset"); + + createMultiClickAction("Default row", "Header", defaultRows, + new Command<Grid, String>() { + + @Override + public void execute(Grid grid, String value, Object data) { + HeaderRow defaultRow = null; + if (value.equals("Top")) { + defaultRow = grid.getHeaderRow(0); + } else if (value.equals("Bottom")) { + defaultRow = grid.getHeaderRow(grid + .getHeaderRowCount() - 1); + } + grid.setDefaultHeaderRow(defaultRow); + } + + }, defaultRows.get("Top")); + + createClickAction("Prepend row", "Header", new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.prependHeaderRow(); + } + + }, null); + createClickAction("Append row", "Header", new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.appendHeaderRow(); + } + + }, null); + + createClickAction("Remove top row", "Header", + new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.removeHeaderRow(0); + } + + }, null); + createClickAction("Remove bottom row", "Header", + new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.removeHeaderRow(grid.getHeaderRowCount() - 1); + } + + }, null); + } + + protected void createFooterActions() { + createCategory("Footer", null); + + createBooleanAction("Visible", "Footer", false, + new Command<Grid, Boolean>() { + + @Override + public void execute(Grid grid, Boolean value, Object data) { + grid.setFooterVisible(value); + } + }); + + createClickAction("Prepend row", "Footer", new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.prependFooterRow(); + } + + }, null); + createClickAction("Append row", "Footer", new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.appendFooterRow(); + } + + }, null); + + createClickAction("Remove top row", "Footer", + new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.removeFooterRow(0); + } + + }, null); + createClickAction("Remove bottom row", "Footer", + new Command<Grid, Object>() { + + @Override + public void execute(Grid grid, Object value, Object data) { + grid.removeFooterRow(grid.getFooterRowCount() - 1); + } + + }, null); + } + + protected void createColumnActions() { + createCategory("Columns", null); + + for (int c = 0; c < COLUMNS; c++) { + final int index = c; + createCategory(getColumnProperty(c), "Columns"); + + createClickAction("Add / Remove", getColumnProperty(c), + new Command<Grid, String>() { + + @Override + public void execute(Grid grid, String value, Object data) { + String columnProperty = getColumnProperty((Integer) data); + if (grid.getColumn(columnProperty) == null) { + grid.addColumn(columnProperty); + } else { + grid.removeColumn(columnProperty); + } + } + }, null, c); + + createBooleanAction("Sortable", getColumnProperty(c), true, + new Command<Grid, Boolean>() { + + @Override + public void execute(Grid grid, Boolean value, + Object columnIndex) { + Object propertyId = getColumnProperty((Integer) columnIndex); + Column column = grid.getColumn(propertyId); + column.setSortable(value); + } + }, c); + + createCategory("Column " + c + " Width", getColumnProperty(c)); + + createClickAction("Auto", "Column " + c + " Width", + new Command<Grid, Integer>() { + + @Override + public void execute(Grid grid, Integer value, + Object columnIndex) { + Object propertyId = getColumnProperty((Integer) columnIndex); + Column column = grid.getColumn(propertyId); + column.setWidthUndefined(); + } + }, -1, c); + + createClickAction("25.5px", "Column " + c + " Width", + new Command<Grid, Void>() { + @Override + @SuppressWarnings("boxing") + public void execute(Grid grid, Void value, + Object columnIndex) { + grid.getColumns().get((Integer) columnIndex) + .setWidth(25.5); + } + }, null, c); + + for (int w = 50; w < 300; w += 50) { + createClickAction(w + "px", "Column " + c + " Width", + new Command<Grid, Integer>() { + + @Override + public void execute(Grid grid, Integer value, + Object columnIndex) { + Object propertyId = getColumnProperty((Integer) columnIndex); + Column column = grid.getColumn(propertyId); + column.setWidth(value); + } + }, w, c); + } + + LinkedHashMap<String, GridStaticCellType> defaultRows = new LinkedHashMap<String, GridStaticCellType>(); + defaultRows.put("Text Header", GridStaticCellType.TEXT); + defaultRows.put("Html Header ", GridStaticCellType.HTML); + defaultRows.put("Widget Header", GridStaticCellType.WIDGET); + + createMultiClickAction("Header Type", getColumnProperty(c), + defaultRows, new Command<Grid, GridStaticCellType>() { + + @Override + public void execute(Grid grid, + GridStaticCellType value, Object columnIndex) { + final Object propertyId = getColumnProperty((Integer) columnIndex); + final HeaderCell cell = grid.getDefaultHeaderRow() + .getCell(propertyId); + switch (value) { + case TEXT: + cell.setText("Text Header"); + break; + case HTML: + cell.setHtml("HTML Header"); + break; + case WIDGET: + cell.setComponent(new Button("Button Header", + new ClickListener() { + + @Override + public void buttonClick( + ClickEvent event) { + log("Button clicked!"); + } + })); + default: + break; + } + } + + }, c); + + defaultRows = new LinkedHashMap<String, GridStaticCellType>(); + defaultRows.put("Text Footer", GridStaticCellType.TEXT); + defaultRows.put("Html Footer", GridStaticCellType.HTML); + defaultRows.put("Widget Footer", GridStaticCellType.WIDGET); + + createMultiClickAction("Footer Type", getColumnProperty(c), + defaultRows, new Command<Grid, GridStaticCellType>() { + + @Override + public void execute(Grid grid, + GridStaticCellType value, Object columnIndex) { + final Object propertyId = getColumnProperty((Integer) columnIndex); + final FooterCell cell = grid.getFooterRow(0) + .getCell(propertyId); + switch (value) { + case TEXT: + cell.setText("Text Footer"); + break; + case HTML: + cell.setHtml("HTML Footer"); + break; + case WIDGET: + cell.setComponent(new Button("Button Footer", + new ClickListener() { + + @Override + public void buttonClick( + ClickEvent event) { + log("Button clicked!"); + } + })); + default: + break; + } + } + + }, c); + } + } + + private static String getColumnProperty(int c) { + return "Column " + c; + } + + protected void createPropertyActions() { + createCategory("Properties", null); + + createBooleanAction("Prepend property", "Properties", false, + new Command<Grid, Boolean>() { + private final Object propertyId = new Object(); + + @Override + public void execute(Grid c, Boolean enable, Object data) { + if (enable.booleanValue()) { + ds.addContainerProperty(propertyId, String.class, + "property value"); + grid.getColumn(propertyId).setHeaderCaption( + "new property"); + grid.setColumnOrder(propertyId); + } else { + ds.removeContainerProperty(propertyId); + } + } + }, null); + } + + protected void createRowActions() { + createCategory("Body rows", null); + + class NewRowCommand implements Command<Grid, String> { + private final int index; + + public NewRowCommand() { + this(0); + } + + public NewRowCommand(int index) { + this.index = index; + } + + @Override + public void execute(Grid c, String value, Object data) { + Item item = ds.addItemAt(index, new Object()); + for (int i = 0; i < COLUMNS; i++) { + Class<?> type = ds.getType(getColumnProperty(i)); + if (String.class.isAssignableFrom(type)) { + Property<String> itemProperty = getProperty(item, i); + itemProperty.setValue("newcell: " + i); + } else if (Integer.class.isAssignableFrom(type)) { + Property<Integer> itemProperty = getProperty(item, i); + itemProperty.setValue(Integer.valueOf(i)); + } else { + // let the default value be taken implicitly. + } + } + } + + private <T extends Object> Property<T> getProperty(Item item, int i) { + @SuppressWarnings("unchecked") + Property<T> itemProperty = item + .getItemProperty(getColumnProperty(i)); + return itemProperty; + } + } + final NewRowCommand newRowCommand = new NewRowCommand(); + + createClickAction("Add 18 rows", "Body rows", + new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + for (int i = 0; i < 18; i++) { + newRowCommand.execute(c, value, data); + } + } + }, null); + + createClickAction("Add first row", "Body rows", newRowCommand, null); + + createClickAction("Add third row", "Body rows", new NewRowCommand(2), + null); + + createClickAction("Remove first row", "Body rows", + new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + Object firstItemId = ds.getIdByIndex(0); + ds.removeItem(firstItemId); + } + }, null); + + createClickAction("Remove 18 first rows", "Body rows", + new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + for (int i = 0; i < 18; i++) { + Object firstItemId = ds.getIdByIndex(0); + ds.removeItem(firstItemId); + } + } + }, null); + + createClickAction("Modify first row (getItemProperty)", "Body rows", + new Command<Grid, String>() { + @SuppressWarnings("unchecked") + @Override + public void execute(Grid c, String value, Object data) { + Object firstItemId = ds.getIdByIndex(0); + Item item = ds.getItem(firstItemId); + for (int i = 0; i < COLUMNS; i++) { + Property<?> property = item + .getItemProperty(getColumnProperty(i)); + if (property.getType().equals(String.class)) { + ((Property<String>) property) + .setValue("modified: " + i); + } + } + } + }, null); + + createClickAction("Modify first row (getContainerProperty)", + "Body rows", new Command<Grid, String>() { + @SuppressWarnings("unchecked") + @Override + public void execute(Grid c, String value, Object data) { + Object firstItemId = ds.getIdByIndex(0); + for (Object containerPropertyId : ds + .getContainerPropertyIds()) { + Property<?> property = ds.getContainerProperty( + firstItemId, containerPropertyId); + if (property.getType().equals(String.class)) { + ((Property<String>) property) + .setValue("modified: " + + containerPropertyId); + } + } + } + }, null); + + createBooleanAction("Select first row", "Body rows", false, + new Command<Grid, Boolean>() { + @Override + public void execute(Grid grid, Boolean select, Object data) { + final Object firstItemId = grid + .getContainerDataSource().firstItemId(); + if (select.booleanValue()) { + grid.select(firstItemId); + } else { + grid.deselect(firstItemId); + } + } + }); + + createClickAction("Remove all rows", "Body rows", + new Command<Grid, String>() { + @SuppressWarnings("unchecked") + @Override + public void execute(Grid c, String value, Object data) { + ds.removeAllItems(); + } + }, null); + } + + protected void createEditorActions() { + createBooleanAction("Enabled", "Editor", false, + new Command<Grid, Boolean>() { + @Override + public void execute(Grid c, Boolean value, Object data) { + c.setEditorEnabled(value); + } + }); + + createClickAction("Edit item 5", "Editor", new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + c.editItem(5); + } + }, null); + + createClickAction("Edit item 100", "Editor", + new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + c.editItem(100); + } + }, null); + createClickAction("Save", "Editor", new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + try { + c.saveEditor(); + } catch (CommitException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }, null); + createClickAction("Cancel edit", "Editor", new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + c.cancelEditor(); + } + }, null); + } + + @SuppressWarnings("boxing") + protected void addHeightActions() { + createCategory("Height by Rows", "Size"); + + createBooleanAction("HeightMode Row", "Size", false, + new Command<Grid, Boolean>() { + @Override + public void execute(Grid c, Boolean heightModeByRows, + Object data) { + c.setHeightMode(heightModeByRows ? HeightMode.ROW + : HeightMode.CSS); + } + }, null); + + addActionForHeightByRows(1d / 3d); + addActionForHeightByRows(2d / 3d); + + for (double i = 1; i < 5; i++) { + addActionForHeightByRows(i); + addActionForHeightByRows(i + 1d / 3d); + addActionForHeightByRows(i + 2d / 3d); + } + + Command<Grid, String> sizeCommand = new Command<Grid, String>() { + @Override + public void execute(Grid grid, String height, Object data) { + grid.setHeight(height); + } + }; + + createCategory("Height", "Size"); + // header 20px + scrollbar 16px = 36px baseline + createClickAction("86px (no drag scroll select)", "Height", + sizeCommand, "86px"); + createClickAction("96px (drag scroll select limit)", "Height", + sizeCommand, "96px"); + createClickAction("106px (drag scroll select enabled)", "Height", + sizeCommand, "106px"); + } + + private void addActionForHeightByRows(final Double i) { + DecimalFormat df = new DecimalFormat("0.00"); + createClickAction(df.format(i) + " rows", "Height by Rows", + new Command<Grid, String>() { + @Override + public void execute(Grid c, String value, Object data) { + c.setHeightByRows(i); + } + }, null); + } + + @Override + protected Integer getTicketNumber() { + return 12829; + } + + @Override + protected Class<Grid> getTestClass() { + return Grid.class; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java new file mode 100644 index 0000000000..0e339ec0ae --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import java.util.ArrayList; +import java.util.List; + +import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public abstract class GridBasicFeaturesTest extends MultiBrowserTest { + + @Override + protected DesiredCapabilities getDesiredCapabilities() { + DesiredCapabilities dCap = super.getDesiredCapabilities(); + if (BrowserUtil.isIE(dCap)) { + dCap.setCapability("requireWindowFocus", true); + } + return super.getDesiredCapabilities(); + } + + @Override + protected Class<?> getUIClass() { + return GridBasicFeatures.class; + } + + protected void selectSubMenu(String menuCaption) { + selectMenu(menuCaption); + new Actions(getDriver()).moveByOffset(100, 0).build().perform(); + } + + protected void selectMenu(String menuCaption) { + getDriver().findElement( + By.xpath("//span[text() = '" + menuCaption + "']")).click(); + } + + protected void selectMenuPath(String... menuCaptions) { + selectMenu(menuCaptions[0]); + for (int i = 1; i < menuCaptions.length; i++) { + selectSubMenu(menuCaptions[i]); + } + } + + protected GridElement getGridElement() { + return ((TestBenchElement) findElement(By.id("testComponent"))) + .wrap(GridElement.class); + } + + protected void scrollGridVerticallyTo(double px) { + executeScript("arguments[0].scrollTop = " + px, + getGridVerticalScrollbar()); + } + + protected int getGridVerticalScrollPos() { + return ((Number) executeScript("return arguments[0].scrollTop", + getGridVerticalScrollbar())).intValue(); + } + + protected List<TestBenchElement> getGridHeaderRowCells() { + List<TestBenchElement> headerCells = new ArrayList<TestBenchElement>(); + for (int i = 0; i < getGridElement().getHeaderCount(); ++i) { + headerCells.addAll(getGridElement().getHeaderCells(i)); + } + return headerCells; + } + + protected List<TestBenchElement> getGridFooterRowCells() { + List<TestBenchElement> footerCells = new ArrayList<TestBenchElement>(); + for (int i = 0; i < getGridElement().getFooterCount(); ++i) { + footerCells.addAll(getGridElement().getFooterCells(i)); + } + return footerCells; + } + + protected WebElement getEditor() { + List<WebElement> elems = getGridElement().findElements( + By.className("v-grid-editor")); + + assertLessThanOrEqual("number of editors", elems.size(), 1); + + return elems.isEmpty() ? null : elems.get(0); + } + + private Object executeScript(String script, WebElement element) { + final WebDriver driver = getDriver(); + if (driver instanceof JavascriptExecutor) { + final JavascriptExecutor je = (JavascriptExecutor) driver; + return je.executeScript(script, element); + } else { + throw new IllegalStateException("current driver " + + getDriver().getClass().getName() + " is not a " + + JavascriptExecutor.class.getSimpleName()); + } + } + + protected WebElement getGridVerticalScrollbar() { + return getDriver() + .findElement( + By.xpath("//div[contains(@class, \"v-grid-scroller-vertical\")]")); + } + + /** + * Reloads the page without restartApplication. This occasionally breaks + * stuff. + */ + protected void reopenTestURL() { + String testUrl = getTestUrl(); + testUrl = testUrl.replace("?restartApplication", "?"); + testUrl = testUrl.replace("?&", "?"); + driver.get(testUrl); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesValo.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesValo.java new file mode 100644 index 0000000000..aef353fe93 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridBasicFeaturesValo.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Theme; +import com.vaadin.ui.themes.ValoTheme; + +@Theme(ValoTheme.THEME_NAME) +public class GridBasicFeaturesValo extends GridBasicFeatures { + @Override + @Deprecated + public String getTheme() { + return ValoTheme.THEME_NAME; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSources.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSources.java new file mode 100644 index 0000000000..3f84d40b01 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSources.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridClientDataSourcesWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; +import com.vaadin.ui.UI; + +@Widgetset(TestingWidgetSet.NAME) +public class GridClientDataSources extends UI { + + @Override + protected void init(VaadinRequest request) { + setContent(new TestWidgetComponent(GridClientDataSourcesWidget.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java new file mode 100644 index 0000000000..30d6541344 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientDataSourcesTest.java @@ -0,0 +1,180 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.JavascriptExecutor; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridClientDataSourcesTest extends MultiBrowserTest { + + @Before + public void before() { + openTestURL(); + } + + @Test + public void normalRestishDatasource() throws Exception { + selectMenuPath("DataSources", "RESTish", "Use"); + assertCellPresent("cell 0 #0"); + + scrollToBottom(); + assertCellPresent("cell 199 #0"); + assertCellNotPresent("cell 200 #0"); + } + + @Test + public void growOnRequestRestishDatasource() throws Exception { + selectMenuPath("DataSources", "RESTish", "Use"); + selectMenuPath("DataSources", "RESTish", "Next request +10"); + + scrollToBottom(); + /* second scroll needed because of scrollsize change after scrolling */ + scrollToBottom(); + + assertCellPresent("cell 209 #1"); + assertCellNotPresent("cell 210 #1"); + } + + @Test + public void shrinkOnRequestRestishDatasource() throws Exception { + selectMenuPath("DataSources", "RESTish", "Use"); + scrollToBottom(); + + selectMenuPath("DataSources", "RESTish", "Next request -10"); + scrollToTop(); + + assertCellPresent("cell 0 #1"); + } + + @Test + public void pushChangeRestishDatasource() throws Exception { + selectMenuPath("DataSources", "RESTish", "Use"); + selectMenuPath("DataSources", "RESTish", "Push data change"); + assertCellPresent("cell 0 #1"); + assertCellNotPresent("cell 0 #0"); + } + + @Test + public void growOnPushRestishDatasource() throws Exception { + selectMenuPath("DataSources", "RESTish", "Use"); + selectMenuPath("DataSources", "RESTish", "Push data change +10"); + assertCellPresent("cell 0 #1"); + assertCellNotPresent("cell 0 #0"); + scrollToBottom(); + assertCellPresent("cell 209 #1"); + } + + @Test + public void shrinkOnPushRestishDatasource() throws Exception { + selectMenuPath("DataSources", "RESTish", "Use"); + scrollToBottom(); + + selectMenuPath("DataSources", "RESTish", "Push data change -10"); + assertCellPresent("cell 189 #1"); + assertCellNotPresent("cell 189 #0"); + assertCellNotPresent("cell 199 #1"); + assertCellNotPresent("cell 199 #0"); + } + + private void assertCellPresent(String content) { + assertNotNull("A cell with content \"" + content + + "\" should've been found", findByXPath("//td[text()='" + + content + "']")); + } + + private void assertCellNotPresent(String content) { + assertNull("A cell with content \"" + content + + "\" should've not been found", findByXPath("//td[text()='" + + content + "']")); + } + + private void scrollToTop() { + scrollVerticallyTo(0); + } + + private void scrollToBottom() { + scrollVerticallyTo(9999); + } + + private WebElement findByXPath(String string) { + if (isElementPresent(By.xpath(string))) { + return findElement(By.xpath(string)); + } else { + return null; + } + } + + private void scrollVerticallyTo(int px) { + executeScript("arguments[0].scrollTop = " + px, findVerticalScrollbar()); + } + + private Object executeScript(String script, Object args) { + final WebDriver driver = getDriver(); + if (driver instanceof JavascriptExecutor) { + final JavascriptExecutor je = (JavascriptExecutor) driver; + return je.executeScript(script, args); + } else { + throw new IllegalStateException("current driver " + + getDriver().getClass().getName() + " is not a " + + JavascriptExecutor.class.getSimpleName()); + } + } + + private WebElement findVerticalScrollbar() { + return getDriver().findElement( + By.xpath("//div[contains(@class, " + + "\"v-grid-scroller-vertical\")]")); + } + + private void selectMenu(String menuCaption) { + WebElement menuElement = getMenuElement(menuCaption); + Dimension size = menuElement.getSize(); + new Actions(getDriver()).moveToElement(menuElement, size.width - 10, + size.height / 2).perform(); + } + + private WebElement getMenuElement(String menuCaption) { + return getDriver().findElement( + By.xpath("//td[text() = '" + menuCaption + "']")); + } + + private void selectMenuPath(String... menuCaptions) { + new Actions(getDriver()).moveToElement(getMenuElement(menuCaptions[0])) + .click().perform(); + for (int i = 1; i < menuCaptions.length - 1; ++i) { + selectMenu(menuCaptions[i]); + new Actions(getDriver()).moveByOffset(20, 0).perform(); + } + new Actions(getDriver()) + .moveToElement( + getMenuElement(menuCaptions[menuCaptions.length - 1])) + .click().perform(); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInit.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInit.java new file mode 100644 index 0000000000..afbe3fcbbb --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInit.java @@ -0,0 +1,20 @@ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Title; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridHeightByRowOnInitWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; +import com.vaadin.ui.UI; + +@Theme("valo") +@Title("Client Grid height by row on init") +@Widgetset(TestingWidgetSet.NAME) +public class GridClientHeightByRowOnInit extends UI { + @Override + protected void init(VaadinRequest request) { + setContent(new TestWidgetComponent(GridHeightByRowOnInitWidget.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java new file mode 100644 index 0000000000..dadaff0eaa --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridClientHeightByRowOnInitTest.java @@ -0,0 +1,19 @@ +package com.vaadin.tests.components.grid.basicfeatures; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@SuppressWarnings("all") +@TestCategory("grid") +public class GridClientHeightByRowOnInitTest extends MultiBrowserTest { + @Test + public void gridHeightIsMoreThanACoupleOfRows() { + openTestURL(); + int height = findElement(By.className("v-grid")).getSize().getHeight(); + assertGreater("Grid should be much taller than 150px (was " + height + + "px)", height, 150); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRenderer.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRenderer.java new file mode 100644 index 0000000000..5c4ccfae89 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRenderer.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridDefaultTextRendererWidget; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; +import com.vaadin.ui.UI; + +@Widgetset(TestingWidgetSet.NAME) +public class GridDefaultTextRenderer extends UI { + + @Override + protected void init(VaadinRequest request) { + setContent(new TestWidgetComponent(GridDefaultTextRendererWidget.class)); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java new file mode 100644 index 0000000000..79eadd03d8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridDefaultTextRendererTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.testbench.elements.ServerClass; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridDefaultTextRendererTest extends MultiBrowserTest { + + @ServerClass("com.vaadin.tests.widgetset.server.TestWidgetComponent") + public static class MyGridElement extends GridElement { + // empty + } + + private GridElement grid; + + @Before + public void init() { + setDebug(true); + openTestURL(); + grid = $(MyGridElement.class).first(); + assertFalse("There was an unexpected notification during init", + $(NotificationElement.class).exists()); + } + + @Test + public void testNullIsRenderedAsEmptyStringByDefaultTextRenderer() { + assertTrue("First cell should've been empty", grid.getCell(0, 0) + .getText().isEmpty()); + } + + @Test + public void testStringIsRenderedAsStringByDefaultTextRenderer() { + assertEquals("Second cell should've been populated ", "string", grid + .getCell(1, 0).getText()); + } + + @Test + public void testWarningShouldNotBeInDebugLog() { + assertFalse("Warning visible with string content.", + isElementPresent(By.xpath("//span[contains(.,'attached:#1')]"))); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInit.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInit.java new file mode 100644 index 0000000000..0b6e6c36dd --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInit.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Title; +import com.vaadin.data.Container; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.grid.HeightMode; +import com.vaadin.ui.Grid; +import com.vaadin.ui.UI; +import com.vaadin.ui.themes.ValoTheme; + +@Title("Server Grid height by row on init") +@Theme(ValoTheme.THEME_NAME) +public class GridHeightByRowOnInit extends UI { + + private static final String PROPERTY = "Property"; + + @Override + protected void init(VaadinRequest request) { + final Grid grid = new Grid(); + Container.Indexed container = grid.getContainerDataSource(); + container.addContainerProperty(PROPERTY, String.class, ""); + + container.addItem("A").getItemProperty(PROPERTY).setValue("A"); + container.addItem("B").getItemProperty(PROPERTY).setValue("B"); + container.addItem("C").getItemProperty(PROPERTY).setValue("C"); + container.addItem("D").getItemProperty(PROPERTY).setValue("D"); + container.addItem("E").getItemProperty(PROPERTY).setValue("E"); + + grid.setHeightMode(HeightMode.ROW); + grid.setHeightByRows(5); + + setContent(grid); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java new file mode 100644 index 0000000000..15a1cd6c85 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridHeightByRowOnInitTest.java @@ -0,0 +1,20 @@ +package com.vaadin.tests.components.grid.basicfeatures; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@SuppressWarnings("all") +@TestCategory("grid") +public class GridHeightByRowOnInitTest extends MultiBrowserTest { + + @Test + public void gridHeightIsMoreThanACoupleOfRows() { + openTestURL(); + int height = $(GridElement.class).first().getSize().getHeight(); + assertGreater("Grid should be much taller than 150px (was " + height + + "px)", height, 150); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicators.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicators.java new file mode 100644 index 0000000000..6d602baf06 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicators.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import com.vaadin.data.Container; +import com.vaadin.data.Item; +import com.vaadin.data.sort.Sort; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.data.sort.SortDirection; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Grid; + +public class GridSortingIndicators extends AbstractTestUI { + + private static int FOO_MIN = 4; + private static int BAR_MULTIPLIER = 3; + private static int BAZ_MAX = 132; + + @Override + protected void setup(VaadinRequest request) { + final Grid grid = new Grid(createContainer()); + addComponent(grid); + grid.sort(Sort.by("foo").then("bar", SortDirection.DESCENDING) + .then("baz")); + + addComponent(new Button("Reverse sorting", new Button.ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + grid.sort(Sort.by("baz", SortDirection.DESCENDING).then("bar") + .then("foo", SortDirection.DESCENDING)); + } + })); + } + + private Container.Indexed createContainer() { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty("foo", Integer.class, 0); + container.addContainerProperty("bar", Integer.class, 0); + container.addContainerProperty("baz", Integer.class, 0); + for (int i = 0; i < 10; ++i) { + Item item = container.getItem(container.addItem()); + item.getItemProperty("foo").setValue(FOO_MIN + i); + item.getItemProperty("baz").setValue(BAZ_MAX - i); + item.getItemProperty("bar").setValue(BAR_MULTIPLIER * i); + } + return container; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java new file mode 100644 index 0000000000..6a5360f152 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridSortingIndicatorsTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.tb3.MultiBrowserTest; + +@TestCategory("grid") +public class GridSortingIndicatorsTest extends MultiBrowserTest { + + @Test + public void testSortingIndicators() throws IOException { + openTestURL(); + compareScreen("initialSort"); + + $(ButtonElement.class).first().click(); + + compareScreen("reversedSort"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/DisabledGridClientTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/DisabledGridClientTest.java new file mode 100644 index 0000000000..63d031bc85 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/DisabledGridClientTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement.GridRowElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; + +public class DisabledGridClientTest extends GridBasicClientFeaturesTest { + + @Before + public void setUp() { + openTestURL(); + selectMenuPath("Component", "State", "Enabled"); + } + + @Test + public void testSelection() { + selectMenuPath("Component", "State", "Selection mode", "single"); + + GridRowElement row = getGridElement().getRow(0); + row.click(); + assertFalse("disabled row should not be selected", row.isSelected()); + + } + + @Test + public void testEditorOpening() { + selectMenuPath("Component", "Editor", "Enabled"); + + GridRowElement row = getGridElement().getRow(0); + row.click(); + assertNull("Editor should not open", getEditor()); + + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + assertNull("Editor should not open", getEditor()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridCellStyleGeneratorTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridCellStyleGeneratorTest.java new file mode 100644 index 0000000000..8188553e61 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridCellStyleGeneratorTest.java @@ -0,0 +1,131 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.GridElement.GridRowElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; +import com.vaadin.tests.widgetset.client.grid.GridBasicClientFeaturesWidget; + +public class GridCellStyleGeneratorTest extends GridBasicClientFeaturesTest { + + @Test + public void testStyleNameGeneratorScrolling() throws Exception { + openTestURL(); + + selectCellStyleNameGenerator(GridBasicClientFeaturesWidget.CELL_STYLE_GENERATOR_COL_INDEX); + selectRowStyleNameGenerator(GridBasicClientFeaturesWidget.ROW_STYLE_GENERATOR_ROW_INDEX); + + GridRowElement row2 = getGridElement().getRow(2); + GridCellElement cell4_2 = getGridElement().getCell(4, 2); + + Assert.assertTrue(hasCssClass(row2, "2")); + Assert.assertTrue(hasCssClass(cell4_2, "4_2")); + + // Scroll down and verify that the old elements don't have the + // stylename any more + + getGridElement().getRow(350); + + Assert.assertFalse(hasCssClass(row2, "2")); + Assert.assertFalse(hasCssClass(cell4_2, "4_2")); + } + + @Test + public void testDisableStyleNameGenerator() throws Exception { + openTestURL(); + + selectCellStyleNameGenerator(GridBasicClientFeaturesWidget.CELL_STYLE_GENERATOR_COL_INDEX); + selectRowStyleNameGenerator(GridBasicClientFeaturesWidget.ROW_STYLE_GENERATOR_ROW_INDEX); + + // Just verify that change was effective + GridRowElement row2 = getGridElement().getRow(2); + GridCellElement cell4_2 = getGridElement().getCell(4, 2); + + Assert.assertTrue(hasCssClass(row2, "2")); + Assert.assertTrue(hasCssClass(cell4_2, "4_2")); + + // Disable the generator and check again + selectCellStyleNameGenerator(GridBasicClientFeaturesWidget.CELL_STYLE_GENERATOR_NONE); + selectRowStyleNameGenerator(GridBasicClientFeaturesWidget.ROW_STYLE_GENERATOR_NONE); + + Assert.assertFalse(hasCssClass(row2, "2")); + Assert.assertFalse(hasCssClass(cell4_2, "4_2")); + } + + @Test + public void testChangeStyleNameGenerator() throws Exception { + openTestURL(); + + selectCellStyleNameGenerator(GridBasicClientFeaturesWidget.CELL_STYLE_GENERATOR_COL_INDEX); + selectRowStyleNameGenerator(GridBasicClientFeaturesWidget.ROW_STYLE_GENERATOR_ROW_INDEX); + + // Just verify that change was effective + GridRowElement row2 = getGridElement().getRow(2); + GridCellElement cell4_2 = getGridElement().getCell(4, 2); + + Assert.assertTrue(hasCssClass(row2, "2")); + Assert.assertTrue(hasCssClass(cell4_2, "4_2")); + + // Change the generator and check again + selectRowStyleNameGenerator(GridBasicClientFeaturesWidget.ROW_STYLE_GENERATOR_NONE); + selectCellStyleNameGenerator(GridBasicClientFeaturesWidget.CELL_STYLE_GENERATOR_SIMPLE); + + // Old styles removed? + Assert.assertFalse(hasCssClass(row2, "2")); + Assert.assertFalse(hasCssClass(cell4_2, "4_2")); + + // New style present? + Assert.assertTrue(hasCssClass(cell4_2, "two")); + } + + @Test + public void testStyleNameGeneratorChangePrimary() throws Exception { + openTestURL(); + + selectCellStyleNameGenerator(GridBasicClientFeaturesWidget.CELL_STYLE_GENERATOR_COL_INDEX); + selectRowStyleNameGenerator(GridBasicClientFeaturesWidget.ROW_STYLE_GENERATOR_ROW_INDEX); + + // Just verify that change was effective + GridRowElement row2 = getGridElement().getRow(2); + GridCellElement cell4_2 = getGridElement().getCell(4, 2); + + Assert.assertTrue(hasCssClass(row2, "2")); + Assert.assertTrue(hasCssClass(cell4_2, "4_2")); + + // Change primary stylename + selectMenuPath("Component", "State", "Primary Stylename", "v-escalator"); + + // Styles still present + Assert.assertTrue(hasCssClass(row2, "2")); + Assert.assertTrue(hasCssClass(cell4_2, "4_2")); + + // New styles present? + Assert.assertFalse(hasCssClass(row2, "v-escalator-row-2")); + Assert.assertFalse(hasCssClass(cell4_2, "v-escalator-cell-content-4_2")); + } + + private void selectCellStyleNameGenerator(String name) { + selectMenuPath("Component", "State", "Cell style generator", name); + } + + private void selectRowStyleNameGenerator(String name) { + selectMenuPath("Component", "State", "Row style generator", name); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java new file mode 100644 index 0000000000..82bf349096 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientColumnPropertiesTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; +import com.vaadin.tests.widgetset.client.grid.GridBasicClientFeaturesWidget; + +public class GridClientColumnPropertiesTest extends GridBasicClientFeaturesTest { + + @Test + public void initialColumnWidths() { + openTestURL(); + + for (int col = 0; col < GridBasicClientFeaturesWidget.COLUMNS; col++) { + int width = getGridElement().getCell(0, col).getSize().getWidth(); + if (col <= 6) { + // Growing column widths + int expectedWidth = 50 + col * 25; + assertEquals("column " + col + " has incorrect width", + expectedWidth, width); + } + } + } + + @Test + public void testChangingColumnWidth() { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 0", "Width", "50px"); + int width = getGridElement().getCell(0, 0).getSize().getWidth(); + assertEquals(50, width); + + selectMenuPath("Component", "Columns", "Column 0", "Width", "200px"); + width = getGridElement().getCell(0, 0).getSize().getWidth(); + assertEquals(200, width); + + selectMenuPath("Component", "Columns", "Column 0", "Width", "auto"); + int autoWidth = getGridElement().getCell(0, 0).getSize().getWidth(); + assertLessThan("Automatic sizing should've shrunk the column", + autoWidth, width); + } + + @Test + public void testFrozenColumns() { + openTestURL(); + + assertFalse(cellIsFrozen(0, 0)); + assertFalse(cellIsFrozen(0, 1)); + + selectMenuPath("Component", "State", "Frozen column count", "1 columns"); + + assertTrue(cellIsFrozen(1, 0)); + assertFalse(cellIsFrozen(1, 1)); + + selectMenuPath("Component", "State", "Selection mode", "multi"); + + assertTrue(cellIsFrozen(1, 1)); + assertFalse(cellIsFrozen(1, 2)); + + selectMenuPath("Component", "State", "Frozen column count", "0 columns"); + + assertTrue(cellIsFrozen(1, 0)); + assertFalse(cellIsFrozen(1, 1)); + + selectMenuPath("Component", "State", "Frozen column count", + "-1 columns"); + + assertFalse(cellIsFrozen(1, 0)); + } + + @Test + public void testBrokenRenderer() { + setDebug(true); + openTestURL(); + + GridElement gridElement = getGridElement(); + + // Scroll first row out of view + gridElement.getRow(50); + + // Enable broken renderer for the first row + selectMenuPath("Component", "Columns", "Column 0", "Broken renderer"); + + // Shouldn't have an error notification yet + assertFalse("Notification was present", + isElementPresent(NotificationElement.class)); + + // Scroll broken row into view and enjoy the chaos + gridElement.getRow(0); + + assertTrue("Notification was not present", + isElementPresent(NotificationElement.class)); + + assertFalse("Text in broken cell should have old value", + "(0, 0)".equals(gridElement.getCell(0, 0).getText())); + + assertEquals("Neighbour cell should be updated", "(0, 1)", gridElement + .getCell(0, 1).getText()); + + assertEquals("Neighbour cell should be updated", "(1, 0)", gridElement + .getCell(1, 0).getText()); + } + + private boolean cellIsFrozen(int row, int col) { + return getGridElement().getCell(row, col).isFrozen(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeEditorTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeEditorTest.java new file mode 100644 index 0000000000..29e6fed68c --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeEditorTest.java @@ -0,0 +1,13 @@ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Before; + +public class GridClientCompositeEditorTest extends GridEditorClientTest { + + @Override + @Before + public void setUp() { + setUseComposite(true); + super.setUp(); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeFooterTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeFooterTest.java new file mode 100644 index 0000000000..26ae7320b0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeFooterTest.java @@ -0,0 +1,11 @@ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Before; + +public class GridClientCompositeFooterTest extends GridFooterTest { + + @Before + public void setUp() { + setUseComposite(true); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeHeaderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeHeaderTest.java new file mode 100644 index 0000000000..c0ed833ab2 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeHeaderTest.java @@ -0,0 +1,11 @@ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Before; + +public class GridClientCompositeHeaderTest extends GridHeaderTest { + + @Before + public void setUp() { + setUseComposite(true); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeKeyEventsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeKeyEventsTest.java new file mode 100644 index 0000000000..a09a31830f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeKeyEventsTest.java @@ -0,0 +1,12 @@ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Before; + +public class GridClientCompositeKeyEventsTest extends + GridClientKeyEventsTest { + + @Before + public void setUp() { + setUseComposite(true); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeSelectionTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeSelectionTest.java new file mode 100644 index 0000000000..7a79a114b8 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientCompositeSelectionTest.java @@ -0,0 +1,11 @@ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Before; + +public class GridClientCompositeSelectionTest extends GridClientSelectionTest { + + @Before + public void setUp() { + setUseComposite(true); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientKeyEventsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientKeyEventsTest.java new file mode 100644 index 0000000000..dc4dedd3a0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientKeyEventsTest.java @@ -0,0 +1,132 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; + +public class GridClientKeyEventsTest extends GridBasicClientFeaturesTest { + + private List<String> eventOrder = Arrays.asList("Down", "Up", "Press"); + + @Test + public void testBodyKeyEvents() throws IOException { + openTestURL(); + + getGridElement().getCell(2, 2).click(); + + new Actions(getDriver()).sendKeys("a").perform(); + + for (int i = 0; i < 3; ++i) { + assertEquals("Body key event handler was not called.", + "(2, 2) event: GridKey" + eventOrder.get(i) + "Event:[" + + (eventOrder.get(i).equals("Press") ? "a" : 65) + + "]", + findElements(By.className("v-label")).get(i * 3).getText()); + + assertTrue("Header key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3 + 1) + .getText().isEmpty()); + assertTrue("Footer key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3 + 2) + .getText().isEmpty()); + } + + } + + @Test + public void testHeaderKeyEvents() throws IOException { + openTestURL(); + + getGridElement().getHeaderCell(0, 2).click(); + + new Actions(getDriver()).sendKeys("a").perform(); + + for (int i = 0; i < 3; ++i) { + assertEquals("Header key event handler was not called.", + "(0, 2) event: GridKey" + eventOrder.get(i) + "Event:[" + + (eventOrder.get(i).equals("Press") ? "a" : 65) + + "]", + findElements(By.className("v-label")).get(i * 3 + 1) + .getText()); + + assertTrue("Body key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3).getText() + .isEmpty()); + assertTrue("Footer key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3 + 2) + .getText().isEmpty()); + } + } + + @Test + public void testFooterKeyEvents() throws IOException { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + getGridElement().getFooterCell(0, 2).click(); + + new Actions(getDriver()).sendKeys("a").perform(); + + for (int i = 0; i < 3; ++i) { + assertEquals("Footer key event handler was not called.", + "(0, 2) event: GridKey" + eventOrder.get(i) + "Event:[" + + (eventOrder.get(i).equals("Press") ? "a" : 65) + + "]", + findElements(By.className("v-label")).get(i * 3 + 2) + .getText()); + + assertTrue("Body key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3).getText() + .isEmpty()); + assertTrue("Header key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3 + 1) + .getText().isEmpty()); + + } + } + + @Test + public void testNoKeyEventsFromWidget() { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 2", "Header Type", + "Widget Header"); + GridCellElement header = getGridElement().getHeaderCell(0, 2); + header.findElement(By.tagName("button")).click(); + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + + for (int i = 0; i < 3; ++i) { + assertTrue("Header key event handler got called unexpectedly.", + findElements(By.className("v-label")).get(i * 3 + 1) + .getText().isEmpty()); + + } + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientSelectionTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientSelectionTest.java new file mode 100644 index 0000000000..d4c10da626 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientSelectionTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; + +public class GridClientSelectionTest extends GridBasicClientFeaturesTest { + + @Test + public void testChangeSelectionMode() { + openTestURL(); + + setSelectionModelNone(); + assertTrue("First column was selection column", getGridElement() + .getCell(0, 0).getText().equals("(0, 0)")); + setSelectionModelMulti(); + assertTrue("First column was not selection column", getGridElement() + .getCell(0, 1).getText().equals("(0, 0)")); + } + + @Test + public void testSelectAllCheckbox() { + openTestURL(); + + setSelectionModelMulti(); + selectMenuPath("Component", "DataSource", "Reset with 100 rows of Data"); + GridCellElement header = getGridElement().getHeaderCell(0, 0); + + assertTrue("No checkbox", header.isElementPresent(By.tagName("input"))); + header.findElement(By.tagName("input")).click(); + + for (int i = 0; i < 100; i += 10) { + assertTrue("Row " + i + " was not selected.", getGridElement() + .getRow(i).isSelected()); + } + + header.findElement(By.tagName("input")).click(); + assertFalse("Row 52 was still selected", getGridElement().getRow(52) + .isSelected()); + } + + @Test + public void testSelectAllCheckboxWhenChangingModels() { + openTestURL(); + + GridCellElement header; + header = getGridElement().getHeaderCell(0, 0); + assertFalse( + "Check box shouldn't have been in header for None Selection Model", + header.isElementPresent(By.tagName("input"))); + + setSelectionModelMulti(); + header = getGridElement().getHeaderCell(0, 0); + assertTrue("Multi Selection Model should have select all checkbox", + header.isElementPresent(By.tagName("input"))); + + setSelectionModelSingle(); + header = getGridElement().getHeaderCell(0, 0); + assertFalse( + "Check box shouldn't have been in header for Single Selection Model", + header.isElementPresent(By.tagName("input"))); + + setSelectionModelNone(); + header = getGridElement().getHeaderCell(0, 0); + assertFalse( + "Check box shouldn't have been in header for None Selection Model", + header.isElementPresent(By.tagName("input"))); + + } + + private void setSelectionModelMulti() { + selectMenuPath("Component", "State", "Selection mode", "multi"); + } + + private void setSelectionModelSingle() { + selectMenuPath("Component", "State", "Selection mode", "single"); + } + + private void setSelectionModelNone() { + selectMenuPath("Component", "State", "Selection mode", "none"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientStructureTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientStructureTest.java new file mode 100644 index 0000000000..74cf368da9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridClientStructureTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; + +@SuppressWarnings("all") +public class GridClientStructureTest extends GridBasicClientFeaturesTest { + @Test + public void haederDecoSizeShouldBeRecalculated() { + // it's easier to notice with valo + openTestURL("theme=valo"); + + WebElement topDeco = getGridElement().findElement( + By.className("v-grid-header-deco")); + assertGreater( + "The header deco in Valo hasn't been recalculated after initial rendering", + topDeco.getSize().getHeight(), 20); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorClientTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorClientTest.java new file mode 100644 index 0000000000..a67b901198 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridEditorClientTest.java @@ -0,0 +1,155 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; + +public class GridEditorClientTest extends GridBasicClientFeaturesTest { + + @Before + public void setUp() { + openTestURL(); + selectMenuPath("Component", "Editor", "Enabled"); + } + + @Test + public void testProgrammaticOpeningClosing() { + selectMenuPath("Component", "Editor", "Edit row 5"); + assertNotNull(getEditor()); + + selectMenuPath("Component", "Editor", "Cancel edit"); + assertNull(getEditor()); + assertEquals("Row 5 edit cancelled", + findElement(By.className("grid-editor-log")).getText()); + } + + @Test + public void testProgrammaticOpeningWithScroll() { + selectMenuPath("Component", "Editor", "Edit row 100"); + assertNotNull(getEditor()); + } + + @Test(expected = NoSuchElementException.class) + public void testVerticalScrollLocking() { + selectMenuPath("Component", "Editor", "Edit row 5"); + getGridElement().getCell(200, 0); + } + + @Test + public void testKeyboardOpeningClosing() { + + getGridElement().getCell(4, 0).click(); + + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + + assertNotNull(getEditor()); + + new Actions(getDriver()).sendKeys(Keys.ESCAPE).perform(); + assertNull(getEditor()); + assertEquals("Row 4 edit cancelled", + findElement(By.className("grid-editor-log")).getText()); + + // Disable editor + selectMenuPath("Component", "Editor", "Enabled"); + + getGridElement().getCell(5, 0).click(); + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + assertNull(getEditor()); + } + + @Test + public void testWidgetBinding() throws Exception { + selectMenuPath("Component", "Editor", "Edit row 100"); + WebElement editor = getEditor(); + + List<WebElement> widgets = editor.findElements(By + .className("gwt-TextBox")); + + assertEquals(GridBasicFeatures.COLUMNS, widgets.size()); + + assertEquals("(100, 0)", widgets.get(0).getAttribute("value")); + assertEquals("(100, 1)", widgets.get(1).getAttribute("value")); + assertEquals("(100, 2)", widgets.get(2).getAttribute("value")); + + assertEquals("100", widgets.get(7).getAttribute("value")); + assertEquals("<b>100</b>", widgets.get(9).getAttribute("value")); + } + + @Test + public void testWithSelectionColumn() throws Exception { + selectMenuPath("Component", "State", "Selection mode", "multi"); + selectMenuPath("Component", "State", "Editor", "Edit row 5"); + + WebElement editor = getEditor(); + List<WebElement> selectorDivs = editor.findElements(By + .cssSelector("div")); + + assertTrue("selector column cell should've been empty", selectorDivs + .get(0).getAttribute("innerHTML").isEmpty()); + assertFalse("normal column cell shoul've had contents", selectorDivs + .get(1).getAttribute("innerHTML").isEmpty()); + } + + @Test + public void testSave() { + selectMenuPath("Component", "Editor", "Edit row 100"); + + WebElement textField = getEditor().findElements( + By.className("gwt-TextBox")).get(0); + + textField.clear(); + textField.sendKeys("Changed"); + + WebElement saveButton = getEditor().findElement( + By.className("v-grid-editor-save")); + + saveButton.click(); + + assertEquals("Changed", getGridElement().getCell(100, 0).getText()); + } + + @Test + public void testProgrammaticSave() { + selectMenuPath("Component", "Editor", "Edit row 100"); + + WebElement textField = getEditor().findElements( + By.className("gwt-TextBox")).get(0); + + textField.clear(); + textField.sendKeys("Changed"); + + selectMenuPath("Component", "Editor", "Save"); + + assertEquals("Changed", getGridElement().getCell(100, 0).getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridFooterTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridFooterTest.java new file mode 100644 index 0000000000..8b65ba315b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridFooterTest.java @@ -0,0 +1,219 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; + +public class GridFooterTest extends GridStaticSectionTest { + + @Test + public void testDefaultFooter() { + openTestURL(); + + // Footer should have zero rows by default + assertFooterCount(0); + } + + @Test + public void testFooterVisibility() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Visible"); + + assertFooterCount(0); + + selectMenuPath("Component", "Footer", "Append row"); + + assertFooterCount(0); + + selectMenuPath("Component", "Footer", "Visible"); + + assertFooterCount(1); + } + + @Test + public void testAddRows() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + assertFooterCount(1); + assertFooterTexts(0, 0); + + selectMenuPath("Component", "Footer", "Prepend row"); + + assertFooterCount(2); + assertFooterTexts(1, 0); + assertFooterTexts(0, 1); + + selectMenuPath("Component", "Footer", "Append row"); + + assertFooterCount(3); + assertFooterTexts(1, 0); + assertFooterTexts(0, 1); + assertFooterTexts(2, 2); + } + + @Test + public void testRemoveRows() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Prepend row"); + selectMenuPath("Component", "Footer", "Append row"); + + selectMenuPath("Component", "Footer", "Remove top row"); + + assertFooterCount(1); + assertFooterTexts(1, 0); + + selectMenuPath("Component", "Footer", "Remove bottom row"); + assertFooterCount(0); + } + + @Test + public void joinColumnsByCells() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + selectMenuPath("Component", "Footer", "Row 1", "Join column cells 0, 1"); + + GridCellElement spannedCell = getGridElement().getFooterCell(0, 0); + assertTrue(spannedCell.isDisplayed()); + assertEquals("2", spannedCell.getAttribute("colspan")); + + // TestBench returns the spanned cell for all columns + assertEquals(spannedCell.getText(), getGridElement() + .getFooterCell(0, 1).getText()); + } + + @Test + public void joinColumnsByColumns() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + selectMenuPath("Component", "Footer", "Row 1", "Join columns 1, 2"); + + GridCellElement spannedCell = getGridElement().getFooterCell(0, 1); + assertTrue(spannedCell.isDisplayed()); + assertEquals("2", spannedCell.getAttribute("colspan")); + + // TestBench returns the spanned cell for all columns + assertEquals(spannedCell.getText(), getGridElement() + .getFooterCell(0, 2).getText()); + } + + @Test + public void joinAllColumnsInRow() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + selectMenuPath("Component", "Footer", "Row 1", "Join all columns"); + + GridCellElement spannedCell = getGridElement().getFooterCell(0, 0); + assertTrue(spannedCell.isDisplayed()); + assertEquals("" + GridBasicFeatures.COLUMNS, + spannedCell.getAttribute("colspan")); + + for (int columnIndex = 1; columnIndex < GridBasicFeatures.COLUMNS; columnIndex++) { + GridCellElement hiddenCell = getGridElement().getFooterCell(0, + columnIndex); + // TestBench returns the spanned cell for all columns + assertEquals(spannedCell.getText(), hiddenCell.getText()); + } + } + + @Test + public void testInitialCellTypes() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + GridCellElement textCell = getGridElement().getFooterCell(0, 0); + /* + * Reindeer has a CSS text transformation that changes the casing so + * that we can't rely on it being what we set + */ + assertEquals("footer (0,0)", textCell.getText().toLowerCase()); + + GridCellElement widgetCell = getGridElement().getFooterCell(0, 1); + assertTrue(widgetCell.isElementPresent(By.className("gwt-HTML"))); + + GridCellElement htmlCell = getGridElement().getFooterCell(0, 2); + assertHTML("<b>Footer (0,2)</b>", htmlCell); + } + + @Test + public void testDynamicallyChangingCellType() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + selectMenuPath("Component", "Columns", "Column 0", "Footer Type", + "Widget Footer"); + GridCellElement widgetCell = getGridElement().getFooterCell(0, 0); + assertTrue(widgetCell.isElementPresent(By.className("gwt-Button"))); + + selectMenuPath("Component", "Columns", "Column 1", "Footer Type", + "HTML Footer"); + GridCellElement htmlCell = getGridElement().getFooterCell(0, 1); + assertHTML("<b>HTML Footer</b>", htmlCell); + + selectMenuPath("Component", "Columns", "Column 2", "Footer Type", + "Text Footer"); + GridCellElement textCell = getGridElement().getFooterCell(0, 2); + + /* + * Reindeer has a CSS text transformation that changes the casing so + * that we can't rely on it being what we set + */ + assertEquals("text footer", textCell.getText().toLowerCase()); + } + + @Test + public void testCellWidgetInteraction() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Append row"); + + selectMenuPath("Component", "Columns", "Column 0", "Footer Type", + "Widget Footer"); + GridCellElement widgetCell = getGridElement().getFooterCell(0, 0); + WebElement button = widgetCell.findElement(By.className("gwt-Button")); + + assertNotEquals("clicked", button.getText().toLowerCase()); + + new Actions(getDriver()).moveToElement(button, 5, 5).click().perform(); + + assertEquals("clicked", button.getText().toLowerCase()); + } + + private void assertFooterCount(int count) { + assertEquals("footer count", count, getGridElement().getFooterCount()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridHeaderTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridHeaderTest.java new file mode 100644 index 0000000000..8cf7f7374f --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridHeaderTest.java @@ -0,0 +1,281 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; + +public class GridHeaderTest extends GridStaticSectionTest { + + @Test + public void testDefaultHeader() throws Exception { + openTestURL(); + + assertHeaderCount(1); + assertHeaderTexts(0, 0); + } + + @Test + public void testHeaderVisibility() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Header", "Visible"); + + assertHeaderCount(0); + + selectMenuPath("Component", "Header", "Append row"); + + assertHeaderCount(0); + + selectMenuPath("Component", "Header", "Visible"); + + assertHeaderCount(2); + } + + @Test + public void testHeaderCaptions() throws Exception { + openTestURL(); + + assertHeaderTexts(0, 0); + } + + @Test + public void testAddRows() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Header", "Append row"); + + assertHeaderCount(2); + assertHeaderTexts(0, 0); + assertHeaderTexts(1, 1); + + selectMenuPath("Component", "Header", "Prepend row"); + + assertHeaderCount(3); + assertHeaderTexts(2, 0); + assertHeaderTexts(0, 1); + assertHeaderTexts(1, 2); + + selectMenuPath("Component", "Header", "Append row"); + + assertHeaderCount(4); + assertHeaderTexts(2, 0); + assertHeaderTexts(0, 1); + assertHeaderTexts(1, 2); + assertHeaderTexts(3, 3); + } + + @Test + public void testRemoveRows() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Header", "Prepend row"); + selectMenuPath("Component", "Header", "Append row"); + + selectMenuPath("Component", "Header", "Remove top row"); + + assertHeaderCount(2); + assertHeaderTexts(0, 0); + assertHeaderTexts(2, 1); + + selectMenuPath("Component", "Header", "Remove bottom row"); + assertHeaderCount(1); + assertHeaderTexts(0, 0); + } + + @Test + public void testDefaultRow() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 0", "Sortable"); + + GridCellElement headerCell = getGridElement().getHeaderCell(0, 0); + + headerCell.click(); + + assertTrue(hasClassName(headerCell, "sort-asc")); + + headerCell.click(); + + assertFalse(hasClassName(headerCell, "sort-asc")); + assertTrue(hasClassName(headerCell, "sort-desc")); + + selectMenuPath("Component", "Header", "Prepend row"); + selectMenuPath("Component", "Header", "Default row", "Top"); + + assertFalse(hasClassName(headerCell, "sort-desc")); + headerCell = getGridElement().getHeaderCell(0, 0); + assertTrue(hasClassName(headerCell, "sort-desc")); + + selectMenuPath("Component", "Header", "Default row", "Unset"); + + assertFalse(hasClassName(headerCell, "sort-desc")); + } + + @Test + public void joinHeaderColumnsByCells() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Header", "Append row"); + + selectMenuPath("Component", "Header", "Row 2", "Join column cells 0, 1"); + + GridCellElement spannedCell = getGridElement().getHeaderCell(1, 0); + assertTrue(spannedCell.isDisplayed()); + assertEquals("2", spannedCell.getAttribute("colspan")); + + // TestBench returns the spanned cell for all spanned columns + GridCellElement hiddenCell = getGridElement().getHeaderCell(1, 1); + assertEquals(spannedCell.getText(), hiddenCell.getText()); + } + + @Test + public void joinHeaderColumnsByColumns() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Header", "Append row"); + + selectMenuPath("Component", "Header", "Row 2", "Join columns 1, 2"); + + GridCellElement spannedCell = getGridElement().getHeaderCell(1, 1); + assertTrue(spannedCell.isDisplayed()); + assertEquals("2", spannedCell.getAttribute("colspan")); + + // TestBench returns the spanned cell for all spanned columns + GridCellElement hiddenCell = getGridElement().getHeaderCell(1, 2); + assertEquals(spannedCell.getText(), hiddenCell.getText()); + } + + @Test + public void joinAllColumnsInHeaderRow() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Header", "Append row"); + + selectMenuPath("Component", "Header", "Row 2", "Join all columns"); + + GridCellElement spannedCell = getGridElement().getHeaderCell(1, 0); + assertTrue(spannedCell.isDisplayed()); + assertEquals("" + GridBasicFeatures.COLUMNS, + spannedCell.getAttribute("colspan")); + + for (int columnIndex = 1; columnIndex < GridBasicFeatures.COLUMNS; columnIndex++) { + // TestBench returns the spanned cell for all spanned columns + GridCellElement hiddenCell = getGridElement().getHeaderCell(1, + columnIndex); + assertEquals(spannedCell.getText(), hiddenCell.getText()); + } + } + + @Test + public void testInitialCellTypes() throws Exception { + openTestURL(); + + GridCellElement textCell = getGridElement().getHeaderCell(0, 0); + + /* + * Reindeer has a CSS text transformation that changes the casing so + * that we can't rely on it being what we set + */ + assertEquals("header (0,0)", textCell.getText().toLowerCase()); + + GridCellElement widgetCell = getGridElement().getHeaderCell(0, 1); + assertTrue(widgetCell.isElementPresent(By.className("gwt-HTML"))); + + GridCellElement htmlCell = getGridElement().getHeaderCell(0, 2); + assertHTML("<b>Header (0,2)</b>", htmlCell); + } + + @Test + public void testDynamicallyChangingCellType() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 0", "Header Type", + "Widget Header"); + GridCellElement widgetCell = getGridElement().getHeaderCell(0, 0); + assertTrue(widgetCell.isElementPresent(By.className("gwt-Button"))); + + selectMenuPath("Component", "Columns", "Column 1", "Header Type", + "HTML Header"); + GridCellElement htmlCell = getGridElement().getHeaderCell(0, 1); + assertHTML("<b>HTML Header</b>", htmlCell); + + selectMenuPath("Component", "Columns", "Column 2", "Header Type", + "Text Header"); + GridCellElement textCell = getGridElement().getHeaderCell(0, 2); + + /* + * Reindeer has a CSS text transformation that changes the casing so + * that we can't rely on it being what we set + */ + assertEquals("text header", textCell.getText().toLowerCase()); + } + + @Test + public void testCellWidgetInteraction() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 0", "Header Type", + "Widget Header"); + GridCellElement widgetCell = getGridElement().getHeaderCell(0, 0); + WebElement button = widgetCell.findElement(By.className("gwt-Button")); + + new Actions(getDriver()).moveToElement(button, 5, 5).click().perform(); + + assertEquals("clicked", button.getText().toLowerCase()); + } + + @Test + public void widgetInSortableCellInteraction() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 0", "Header Type", + "Widget Header"); + + selectMenuPath("Component", "Columns", "Column 0", "Sortable"); + + GridCellElement widgetCell = getGridElement().getHeaderCell(0, 0); + WebElement button = widgetCell.findElement(By.className("gwt-Button")); + + assertNotEquals("clicked", button.getText().toLowerCase()); + + new Actions(getDriver()).moveToElement(button, 5, 5).click().perform(); + + assertEquals("clicked", button.getText().toLowerCase()); + } + + private void assertHeaderCount(int count) { + assertEquals("header count", count, getGridElement().getHeaderCount()); + } + + private boolean hasClassName(TestBenchElement element, String name) { + return Arrays.asList(element.getAttribute("class").split(" ")) + .contains(name); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridRowHandleRefreshTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridRowHandleRefreshTest.java new file mode 100644 index 0000000000..c7a509da45 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridRowHandleRefreshTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; + +public class GridRowHandleRefreshTest extends GridBasicClientFeaturesTest { + + @Test + public void testRefreshingThroughRowHandle() { + openTestURL(); + + assertEquals("Unexpected initial state", "(0, 0)", getGridElement() + .getCell(0, 0).getText()); + selectMenuPath("Component", "State", "Edit and refresh Row 0"); + assertEquals("Cell contents did not update correctly", "Foo", + getGridElement().getCell(0, 0).getText()); + } + + @Test + public void testDelayedRefreshingThroughRowHandle() + throws InterruptedException { + openTestURL(); + + assertEquals("Unexpected initial state", "(0, 0)", getGridElement() + .getCell(0, 0).getText()); + selectMenuPath("Component", "State", "Delayed edit of Row 0"); + // Still the same data + assertEquals("Cell contents did not update correctly", "(0, 0)", + getGridElement().getCell(0, 0).getText()); + sleep(5000); + // Data should be updated + assertEquals("Cell contents did not update correctly", "Bar", + getGridElement().getCell(0, 0).getText()); + } + + @Test + public void testRefreshingWhenNotInViewThroughRowHandle() { + openTestURL(); + + assertEquals("Unexpected initial state", "(0, 0)", getGridElement() + .getCell(0, 0).getText()); + getGridElement().scrollToRow(100); + selectMenuPath("Component", "State", "Edit and refresh Row 0"); + assertEquals("Cell contents did not update correctly", "Foo", + getGridElement().getCell(0, 0).getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridStaticSectionTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridStaticSectionTest.java new file mode 100644 index 0000000000..cc801bf870 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridStaticSectionTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; + +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; + +/** + * Abstract base class for header and footer tests. + * + * @since + * @author Vaadin Ltd + */ +public abstract class GridStaticSectionTest extends GridBasicClientFeaturesTest { + + protected void assertHeaderTexts(int headerId, int rowIndex) { + int i = 0; + for (TestBenchElement cell : getGridElement().getHeaderCells(rowIndex)) { + + if (i % 3 == 0) { + assertText(String.format("Header (%d,%d)", headerId, i), cell); + } else if (i % 2 == 0) { + assertHTML(String.format("<b>Header (%d,%d)</b>", headerId, i), + cell); + } else { + assertHTML(String.format( + "<div class=\"gwt-HTML\">Header (%d,%d)</div>", + headerId, i), cell); + } + + i++; + } + assertEquals("number of header columns", GridBasicFeatures.COLUMNS, i); + } + + protected void assertFooterTexts(int footerId, int rowIndex) { + int i = 0; + for (TestBenchElement cell : getGridElement().getFooterCells(rowIndex)) { + if (i % 3 == 0) { + assertText(String.format("Footer (%d,%d)", footerId, i), cell); + } else if (i % 2 == 0) { + assertHTML(String.format("<b>Footer (%d,%d)</b>", footerId, i), + cell); + } else { + assertHTML(String.format( + "<div class=\"gwt-HTML\">Footer (%d,%d)</div>", + footerId, i), cell); + } + i++; + } + assertEquals("number of footer columns", GridBasicFeatures.COLUMNS, i); + } + + protected static void assertText(String text, TestBenchElement e) { + // TBE.getText returns "" if the element is scrolled out of view + assertEquals(text, e.getAttribute("innerHTML")); + } + + protected static void assertHTML(String text, TestBenchElement e) { + String html = e.getAttribute("innerHTML"); + + // IE 8 returns tags as upper case while other browsers do not, make the + // comparison non-casesensive + html = html.toLowerCase(); + text = text.toLowerCase(); + + // IE 8 returns attributes without quotes, make the comparison without + // quotes + html = html.replaceAll("\"", ""); + text = html.replaceAll("\"", ""); + + assertEquals(text, html); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridStylingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridStylingTest.java new file mode 100644 index 0000000000..cbf27a69d9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridStylingTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.client; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.By; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; + +public class GridStylingTest extends GridStaticSectionTest { + + @Test + public void testGridPrimaryStyle() throws Exception { + openTestURL(); + + validateStylenames("v-grid"); + } + + @Test + public void testChangingPrimaryStyleName() throws Exception { + openTestURL(); + + selectMenuPath("Component", "State", "Primary Stylename", + "v-custom-style"); + + validateStylenames("v-custom-style"); + } + + private void validateStylenames(String stylename) { + + String classNames = getGridElement().getAttribute("class"); + assertEquals(stylename, classNames); + + classNames = getGridElement().getVerticalScroller().getAttribute( + "class"); + assertTrue(classNames.contains(stylename + "-scroller")); + assertTrue(classNames.contains(stylename + "-scroller-vertical")); + + classNames = getGridElement().getHorizontalScroller().getAttribute( + "class"); + assertTrue(classNames.contains(stylename + "-scroller")); + assertTrue(classNames.contains(stylename + "-scroller-horizontal")); + + classNames = getGridElement().getTableWrapper().getAttribute("class"); + assertEquals(stylename + "-tablewrapper", classNames); + + classNames = getGridElement().getHeader().getAttribute("class"); + assertEquals(stylename + "-header", classNames); + + for (int row = 0; row < getGridElement().getHeaderCount(); row++) { + classNames = getGridElement().getHeaderRow(row).getAttribute( + "class"); + assertEquals(stylename + "-row", classNames); + + for (int col = 0; col < GridBasicFeatures.COLUMNS; col++) { + classNames = getGridElement().getHeaderCell(row, col) + .getAttribute("class"); + assertTrue(classNames.contains(stylename + "-cell")); + } + } + + classNames = getGridElement().getBody().getAttribute("class"); + assertEquals(stylename + "-body", classNames); + + int rowsInBody = getGridElement().getBody() + .findElements(By.tagName("tr")).size(); + for (int row = 0; row < rowsInBody; row++) { + classNames = getGridElement().getRow(row).getAttribute("class"); + assertTrue(classNames.contains(stylename + "-row")); + assertTrue(classNames.contains(stylename + "-row-has-data")); + + for (int col = 0; col < GridBasicFeatures.COLUMNS; col++) { + classNames = getGridElement().getCell(row, col).getAttribute( + "class"); + assertTrue(classNames.contains(stylename + "-cell")); + + if (row == 0 && col == 0) { + assertTrue(classNames.contains(stylename + "-cell-focused")); + } + } + } + + classNames = getGridElement().getFooter().getAttribute("class"); + assertEquals(stylename + "-footer", classNames); + + for (int row = 0; row < getGridElement().getFooterCount(); row++) { + classNames = getGridElement().getFooterRow(row).getAttribute( + "class"); + assertEquals(stylename + "-row", classNames); + + for (int col = 0; col < GridBasicFeatures.COLUMNS; col++) { + classNames = getGridElement().getFooterCell(row, col) + .getAttribute("class"); + assertTrue(classNames.contains(stylename + "-cell")); + } + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java new file mode 100644 index 0000000000..95ed6ab3ff --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorBasicsTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +import java.io.IOException; + +import org.junit.Test; + +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; + +public class EscalatorBasicsTest extends EscalatorBasicClientFeaturesTest { + + @Test + public void testDetachingAnEmptyEscalator() { + setDebug(true); + openTestURL(); + + selectMenuPath(GENERAL, DETACH_ESCALATOR); + assertEscalatorIsRemovedCorrectly(); + } + + @Test + public void testDetachingASemiPopulatedEscalator() throws IOException { + setDebug(true); + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, ADD_ONE_OF_EACH_ROW); + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + selectMenuPath(GENERAL, DETACH_ESCALATOR); + assertEscalatorIsRemovedCorrectly(); + } + + @Test + public void testDetachingAPopulatedEscalator() { + setDebug(true); + openTestURL(); + + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + selectMenuPath(GENERAL, DETACH_ESCALATOR); + assertEscalatorIsRemovedCorrectly(); + } + + private void assertEscalatorIsRemovedCorrectly() { + assertFalse($(NotificationElement.class).exists()); + assertNull(getEscalator()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java new file mode 100644 index 0000000000..d9b3debbe1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColspanTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; + +public class EscalatorColspanTest extends EscalatorBasicClientFeaturesTest { + private static final int NO_COLSPAN = 1; + + @Test + public void testNoColspan() { + openTestURL(); + populate(); + + assertEquals(NO_COLSPAN, getColSpan(getHeaderCell(0, 0))); + assertEquals(NO_COLSPAN, getColSpan(getBodyCell(0, 0))); + assertEquals(NO_COLSPAN, getColSpan(getFooterCell(0, 0))); + } + + @Test + public void testColspan() { + openTestURL(); + populate(); + + int firstCellWidth = getBodyCell(0, 0).getSize().getWidth(); + int secondCellWidth = getBodyCell(0, 1).getSize().getWidth(); + int doubleCellWidth = firstCellWidth + secondCellWidth; + + selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL); + + WebElement bodyCell = getBodyCell(0, 0); + assertEquals("Cell was not spanned correctly", 2, getColSpan(bodyCell)); + assertEquals( + "Spanned cell's width was not the sum of the previous cells (" + + firstCellWidth + " + " + secondCellWidth + ")", + doubleCellWidth, bodyCell.getSize().getWidth(), 1); + } + + @Test + public void testColspanToggle() { + openTestURL(); + populate(); + + int singleCellWidth = getBodyCell(0, 0).getSize().getWidth(); + + selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NORMAL); + selectMenuPath(FEATURES, COLUMN_SPANNING, COLSPAN_NONE); + + WebElement bodyCell = getBodyCell(0, 0); + assertEquals(NO_COLSPAN, getColSpan(bodyCell)); + assertEquals(singleCellWidth, bodyCell.getSize().getWidth(), 1); + } + + private static int getColSpan(WebElement cell) { + String attribute = cell.getAttribute("colspan"); + if (attribute == null) { + return NO_COLSPAN; + } else { + return Integer.parseInt(attribute); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColumnFreezingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColumnFreezingTest.java new file mode 100644 index 0000000000..e808001cf7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorColumnFreezingTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.junit.Test; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; + +public class EscalatorColumnFreezingTest extends + EscalatorBasicClientFeaturesTest { + + private final static Pattern TRANSFORM_PATTERN = Pattern.compile(// @formatter:off + // any start of the string + ".*" + + // non-capturing group for "webkitTransform: " or "transform: " + + "(?:webkitT|t)ransform: " + + // non-capturing group for "translate" or "translate3d" + + "translate(?:3d)?" + + // capturing the digits in e.g "(100px," + + "\\((\\d+)px," + + // any end of the string + + ".*", Pattern.CASE_INSENSITIVE); + + // @formatter:on + + private final static Pattern LEFT_PATTERN = Pattern.compile( + ".*left: (\\d+)px.*", Pattern.CASE_INSENSITIVE); + + private static final int NO_FREEZE = -1; + + @Test + public void testNoFreeze() { + openTestURL(); + populate(); + + WebElement bodyCell = getBodyCell(0, 0); + assertFalse(isFrozen(bodyCell)); + assertEquals(NO_FREEZE, getFrozenScrollCompensation(bodyCell)); + } + + @Test + public void testOneFreeze() { + openTestURL(); + populate(); + + selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_1_COLUMN); + int scrollPx = 60; + scrollHorizontallyTo(scrollPx); + + WebElement bodyCell = getBodyCell(0, 0); + assertTrue(isFrozen(bodyCell)); + assertEquals(scrollPx, getFrozenScrollCompensation(bodyCell)); + } + + @Test + public void testFreezeToggle() { + openTestURL(); + populate(); + + selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_1_COLUMN); + scrollHorizontallyTo(100); + selectMenuPath(FEATURES, FROZEN_COLUMNS, FREEZE_0_COLUMNS); + + WebElement bodyCell = getBodyCell(0, 0); + assertFalse(isFrozen(bodyCell)); + assertEquals(NO_FREEZE, getFrozenScrollCompensation(bodyCell)); + } + + private static boolean isFrozen(WebElement cell) { + return cell.getAttribute("class").contains("frozen"); + } + + private static int getFrozenScrollCompensation(WebElement cell) { + String styleAttribute = cell.getAttribute("style"); + Matcher transformMatcher = TRANSFORM_PATTERN.matcher(styleAttribute); + Matcher leftMatcher = LEFT_PATTERN.matcher(styleAttribute); + + if (transformMatcher.find()) { + return Integer.parseInt(transformMatcher.group(1)); + } else if (leftMatcher.find()) { + return Integer.parseInt(leftMatcher.group(1)); + } else { + return NO_FREEZE; + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java new file mode 100644 index 0000000000..e72e8fae70 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorRowColumnTest.java @@ -0,0 +1,316 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; + +public class EscalatorRowColumnTest extends EscalatorBasicClientFeaturesTest { + + /** + * The scroll position of the Escalator when scrolled all the way down, to + * reveal the 100:th row. + */ + private static final int BOTTOM_SCROLL_POSITION = 1857; + + @Test + public void testInit() { + openTestURL(); + assertNotNull(getEscalator()); + assertNull(getHeaderRow(0)); + assertNull(getBodyRow(0)); + assertNull(getFooterRow(0)); + + assertLogContains("Columns: 0"); + assertLogContains("Header rows: 0"); + assertLogContains("Body rows: 0"); + assertLogContains("Footer rows: 0"); + } + + @Test + public void testInsertAColumn() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + assertNull(getHeaderRow(0)); + assertNull(getBodyRow(0)); + assertNull(getFooterRow(0)); + assertLogContains("Columns: 1"); + } + + @Test + public void testInsertAHeaderRow() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Header rows: 1"); + } + + @Test + public void testInsertABodyRow() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Body rows: 1"); + } + + @Test + public void testInsertAFooterRow() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Footer rows: 1"); + } + + @Test + public void testInsertAColumnAndAHeaderRow() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING); + assertNotNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Columns: 1"); + assertLogContains("Header rows: 1"); + } + + @Test + public void testInsertAColumnAndABodyRow() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNotNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Columns: 1"); + assertLogContains("Body rows: 1"); + } + + @Test + public void testInsertAColumnAndAFooterRow() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNotNull(getFooterCell(0, 0)); + assertLogContains("Columns: 1"); + assertLogContains("Footer rows: 1"); + } + + @Test + public void testInsertAHeaderRowAndAColumn() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, ADD_ONE_ROW_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + assertNotNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Columns: 1"); + assertLogContains("Header rows: 1"); + } + + @Test + public void testInsertABodyRowAndAColumn() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, ADD_ONE_ROW_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNotNull(getBodyCell(0, 0)); + assertNull(getFooterCell(0, 0)); + assertLogContains("Columns: 1"); + assertLogContains("Body rows: 1"); + } + + @Test + public void testInsertAFooterRowAndAColumn() { + openTestURL(); + + selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, ADD_ONE_ROW_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, ADD_ONE_COLUMN_TO_BEGINNING); + assertNull(getHeaderCell(0, 0)); + assertNull(getBodyCell(0, 0)); + assertNotNull(getFooterCell(0, 0)); + assertLogContains("Columns: 1"); + assertLogContains("Footer rows: 1"); + } + + @Test + public void testFillColRow() { + openTestURL(); + + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + scrollVerticallyTo(2000); // more like 1857, but this should be enough. + + // if not found, an exception is thrown here + assertTrue("Wanted cell was not visible", + isElementPresent(By.xpath("//td[text()='Cell: 9,99']"))); + } + + @Test + public void testFillRowCol() { + openTestURL(); + + selectMenuPath(GENERAL, POPULATE_ROW_COLUMN); + scrollVerticallyTo(2000); // more like 1857, but this should be enough. + + // if not found, an exception is thrown here + assertTrue("Wanted cell was not visible", + isElementPresent(By.xpath("//td[text()='Cell: 9,99']"))); + } + + @Test + public void testClearColRow() { + openTestURL(); + + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + selectMenuPath(GENERAL, CLEAR_COLUMN_ROW); + + assertNull(getBodyCell(0, 0)); + } + + @Test + public void testClearRowCol() { + openTestURL(); + + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + selectMenuPath(GENERAL, CLEAR_ROW_COLUMN); + + assertNull(getBodyCell(0, 0)); + } + + @Test + public void testResizeColToFit() { + openTestURL(); + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, RESIZE_FIRST_COLUMN_TO_100PX); + int originalWidth = getBodyCell(0, 0).getSize().getWidth(); + + assertEquals(100, originalWidth); + + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, + RESIZE_FIRST_COLUMN_TO_MAX_WIDTH); + int newWidth = getBodyCell(0, 0).getSize().getWidth(); + assertNotEquals("Column width should've changed", originalWidth, + newWidth); + } + + @Test + public void testRemoveMoreThanPagefulAtBottomWhileScrolledToBottom() + throws Exception { + openTestURL(); + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + scrollVerticallyTo(BOTTOM_SCROLL_POSITION); + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_50_ROWS_FROM_BOTTOM); + assertEquals("Row 49: 0,49", getBodyCell(-1, 0).getText()); + + scrollVerticallyTo(0); + + // let the DOM organize itself + Thread.sleep(500); + + // if something goes wrong, it'll explode before this. + assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText()); + } + + @Test + public void testRemoveMoreThanPagefulAtBottomWhileScrolledAlmostToBottom() + throws Exception { + openTestURL(); + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + // bottom minus 15 rows. + scrollVerticallyTo(BOTTOM_SCROLL_POSITION - 15 * 20); + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_50_ROWS_FROM_BOTTOM); + assertEquals("Row 49: 0,49", getBodyCell(-1, 0).getText()); + + scrollVerticallyTo(0); + + // let the DOM organize itself + Thread.sleep(500); + + // if something goes wrong, it'll explode before this. + assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText()); + } + + @Test + public void testRemoveMoreThanPagefulNearBottomWhileScrolledToBottom() + throws Exception { + openTestURL(); + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + scrollVerticallyTo(BOTTOM_SCROLL_POSITION); + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, + REMOVE_50_ROWS_FROM_ALMOST_BOTTOM); + assertEquals("Row 49: 0,99", getBodyCell(-1, 0).getText()); + + scrollVerticallyTo(0); + + // let the DOM organize itself + Thread.sleep(500); + + // if something goes wrong, it'll explode before this. + assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText()); + } + + @Test + public void testRemoveMoreThanPagefulNearBottomWhileScrolledAlmostToBottom() + throws Exception { + openTestURL(); + selectMenuPath(GENERAL, POPULATE_COLUMN_ROW); + + // bottom minus 15 rows. + scrollVerticallyTo(BOTTOM_SCROLL_POSITION - 15 * 20); + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, + REMOVE_50_ROWS_FROM_ALMOST_BOTTOM); + + // let the DOM organize itself + Thread.sleep(500); + assertEquals("Row 49: 0,99", getBodyCell(-1, 0).getText()); + + scrollVerticallyTo(0); + + // let the DOM organize itself + Thread.sleep(500); + + // if something goes wrong, it'll explode before this. + assertEquals("Row 0: 0,0", getBodyCell(0, 0).getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorScrollTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorScrollTest.java new file mode 100644 index 0000000000..41ad370b98 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorScrollTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; + +@SuppressWarnings("all") +public class EscalatorScrollTest extends EscalatorBasicClientFeaturesTest { + + @Before + public void setUp() { + openTestURL(); + populate(); + } + + /** + * Before the fix, removing and adding rows and also scrolling would put the + * scroll state in an internally inconsistent state. The scrollbar would've + * been scrolled correctly, but the body wasn't. + * + * This was due to optimizations that didn't keep up with the promises, so + * to say. So the optimizations were removed. + */ + @Test + public void testScrollRaceCondition() { + scrollVerticallyTo(40); + String originalStyle = getTBodyStyle(); + selectMenuPath(COLUMNS_AND_ROWS, BODY_ROWS, REMOVE_ALL_INSERT_SCROLL); + + // body should be scrolled to exactly the same spot. (not 0) + assertEquals(originalStyle, getTBodyStyle()); + } + + @Test + public void scrollToBottomAndRemoveHeader() throws Exception { + scrollVerticallyTo(999999); // to bottom + + /* + * apparently the scroll event isn't fired by the time the next assert + * would've been done. + */ + Thread.sleep(50); + + assertEquals("Unexpected last row cell before header removal", + "Row 99: 0,99", getBodyCell(-1, 0).getText()); + selectMenuPath(COLUMNS_AND_ROWS, HEADER_ROWS, + REMOVE_ONE_ROW_FROM_BEGINNING); + assertEquals("Unexpected last row cell after header removal", + "Row 99: 0,99", getBodyCell(-1, 0).getText()); + + } + + @Test + public void scrollToBottomAndRemoveFooter() throws Exception { + scrollVerticallyTo(999999); // to bottom + + /* + * apparently the scroll event isn't fired by the time the next assert + * would've been done. + */ + Thread.sleep(50); + + assertEquals("Unexpected last row cell before footer removal", + "Row 99: 0,99", getBodyCell(-1, 0).getText()); + selectMenuPath(COLUMNS_AND_ROWS, FOOTER_ROWS, + REMOVE_ONE_ROW_FROM_BEGINNING); + assertEquals("Unexpected last row cell after footer removal", + "Row 99: 0,99", getBodyCell(-1, 0).getText()); + } + + private String getTBodyStyle() { + WebElement tbody = getEscalator().findElement(By.tagName("tbody")); + return tbody.getAttribute("style"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorUpdaterUiTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorUpdaterUiTest.java new file mode 100644 index 0000000000..85d3fc0bac --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/escalator/EscalatorUpdaterUiTest.java @@ -0,0 +1,151 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.escalator; + +import org.junit.Test; + +import com.vaadin.tests.components.grid.basicfeatures.EscalatorBasicClientFeaturesTest; +import com.vaadin.tests.components.grid.basicfeatures.EscalatorUpdaterUi; + +public class EscalatorUpdaterUiTest extends EscalatorBasicClientFeaturesTest { + @Override + protected Class<?> getUIClass() { + return EscalatorUpdaterUi.class; + } + + @Test + public void testHeaderPaintOrderRowColRowCol() { + boolean addColumnFirst = false; + boolean removeColumnFirst = false; + testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testHeaderPaintOrderRowColColRow() { + boolean addColumnFirst = false; + boolean removeColumnFirst = true; + testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testHeaderPaintOrderColRowColRow() { + boolean addColumnFirst = true; + boolean removeColumnFirst = true; + testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testHeaderPaintOrderColRowRowCol() { + boolean addColumnFirst = true; + boolean removeColumnFirst = false; + testPaintOrder(HEADER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testBodyPaintOrderRowColRowCol() { + boolean addColumnFirst = false; + boolean removeColumnFirst = false; + testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testBodyPaintOrderRowColColRow() { + boolean addColumnFirst = false; + boolean removeColumnFirst = true; + testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testBodyPaintOrderColRowColRow() { + boolean addColumnFirst = true; + boolean removeColumnFirst = true; + testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testBodyPaintOrderColRowRowCol() { + boolean addColumnFirst = true; + boolean removeColumnFirst = false; + testPaintOrder(BODY_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testFooterPaintOrderRowColRowCol() { + boolean addColumnFirst = false; + boolean removeColumnFirst = false; + testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testFooterPaintOrderRowColColRow() { + boolean addColumnFirst = false; + boolean removeColumnFirst = true; + testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testFooterPaintOrderColRowColRow() { + boolean addColumnFirst = true; + boolean removeColumnFirst = true; + testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst); + } + + @Test + public void testFooterPaintOrderColRowRowCol() { + boolean addColumnFirst = true; + boolean removeColumnFirst = false; + testPaintOrder(FOOTER_ROWS, addColumnFirst, removeColumnFirst); + } + + private void testPaintOrder(String tableSection, boolean addColumnFirst, + boolean removeColumnFirst) { + openTestURL(); + + if (addColumnFirst) { + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, + ADD_ONE_COLUMN_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, tableSection, + ADD_ONE_ROW_TO_BEGINNING); + } else { + selectMenuPath(COLUMNS_AND_ROWS, tableSection, + ADD_ONE_ROW_TO_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, + ADD_ONE_COLUMN_TO_BEGINNING); + } + + assertLogContainsInOrder("preAttach: elementIsAttached == false", + "postAttach: elementIsAttached == true", + "update: elementIsAttached == true"); + assertLogDoesNotContain("preDetach"); + assertLogDoesNotContain("postDetach"); + + if (removeColumnFirst) { + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, + REMOVE_ONE_COLUMN_FROM_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, tableSection, + REMOVE_ONE_ROW_FROM_BEGINNING); + } else { + selectMenuPath(COLUMNS_AND_ROWS, tableSection, + REMOVE_ONE_ROW_FROM_BEGINNING); + selectMenuPath(COLUMNS_AND_ROWS, COLUMNS, + REMOVE_ONE_COLUMN_FROM_BEGINNING); + } + + assertLogContainsInOrder("preDetach: elementIsAttached == true", + "postDetach: elementIsAttached == false"); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/DisabledGridTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/DisabledGridTest.java new file mode 100644 index 0000000000..ed1234e608 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/DisabledGridTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement.GridRowElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class DisabledGridTest extends GridBasicFeaturesTest { + + @Before + public void setUp() { + openTestURL(); + selectMenuPath("Component", "State", "Enabled"); + } + + @Test + public void testSelection() { + selectMenuPath("Component", "State", "Selection mode", "single"); + + GridRowElement row = getGridElement().getRow(0); + row.click(); + assertFalse("disabled row should not be selected", row.isSelected()); + + } + + @Test + public void testEditorOpening() { + selectMenuPath("Component", "Editor", "Enabled"); + + GridRowElement row = getGridElement().getRow(0); + row.click(); + assertNull("Editor should not open", getEditor()); + + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + assertNull("Editor should not open", getEditor()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellFocusAdjustmentTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellFocusAdjustmentTest.java new file mode 100644 index 0000000000..0c26ceb5c9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellFocusAdjustmentTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridCellFocusAdjustmentTest extends GridBasicFeaturesTest { + + @Test + public void testCellFocusWithAddAndRemoveRows() { + openTestURL(); + GridElement grid = getGridElement(); + + grid.getCell(0, 0).click(); + + selectMenuPath("Component", "Body rows", "Add first row"); + assertTrue("Cell focus was not moved when adding a row", + grid.getCell(1, 0).isFocused()); + + selectMenuPath("Component", "Body rows", "Add 18 rows"); + assertTrue("Cell focus was not moved when adding multiple rows", grid + .getCell(19, 0).isFocused()); + + for (int i = 18; i <= 0; --i) { + selectMenuPath("Component", "Body rows", "Remove first row"); + assertTrue("Cell focus was not moved when removing a row", grid + .getCell(i, 0).isFocused()); + } + } + + @Test + public void testCellFocusOffsetWhileInDifferentSection() { + openTestURL(); + getGridElement().getCell(0, 0).click(); + new Actions(getDriver()).sendKeys(Keys.UP).perform(); + assertTrue("Header 0,0 should've become focused", getGridElement() + .getHeaderCell(0, 0).isFocused()); + + selectMenuPath("Component", "Body rows", "Add first row"); + assertTrue("Header 0,0 should've remained focused", getGridElement() + .getHeaderCell(0, 0).isFocused()); + } + + @Test + public void testCellFocusOffsetWhileInSameSectionAndInsertedAbove() { + openTestURL(); + assertTrue("Body 0,0 should've gotten focus", + getGridElement().getCell(0, 0).isFocused()); + + selectMenuPath("Component", "Body rows", "Add first row"); + assertTrue("Body 1,0 should've gotten focus", + getGridElement().getCell(1, 0).isFocused()); + } + + @Test + public void testCellFocusOffsetWhileInSameSectionAndInsertedBelow() { + openTestURL(); + assertTrue("Body 0,0 should've gotten focus", + getGridElement().getCell(0, 0).isFocused()); + + selectMenuPath("Component", "Body rows", "Add third row"); + assertTrue("Body 0,0 should've remained focused", getGridElement() + .getCell(0, 0).isFocused()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellStyleGeneratorTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellStyleGeneratorTest.java new file mode 100644 index 0000000000..643c61d90a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridCellStyleGeneratorTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertFalse; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.GridElement.GridRowElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridCellStyleGeneratorTest extends GridBasicFeaturesTest { + @Test + public void testStyleNameGeneratorScrolling() throws Exception { + openTestURL(); + + selectRowStyleNameGenerator(GridBasicFeatures.ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4); + selectCellStyleNameGenerator(GridBasicFeatures.CELL_STYLE_GENERATOR_SPECIAL); + + GridRowElement row = getGridElement().getRow(2); + GridCellElement cell = getGridElement().getCell(3, 2); + + Assert.assertTrue(hasCssClass(row, "row2")); + Assert.assertTrue(hasCssClass(cell, "Column_2")); + + // Scroll down and verify that the old elements don't have the + // stylename any more + + // Carefully chosen offset to hit an index % 4 without cell style + row = getGridElement().getRow(352); + cell = getGridElement().getCell(353, 2); + + Assert.assertFalse(hasCssClass(row, "row352")); + Assert.assertFalse(hasCssClass(cell, "Column_2")); + } + + @Test + public void testDisableStyleNameGenerator() throws Exception { + openTestURL(); + + selectRowStyleNameGenerator(GridBasicFeatures.ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4); + selectCellStyleNameGenerator(GridBasicFeatures.CELL_STYLE_GENERATOR_SPECIAL); + + // Just verify that change was effective + GridRowElement row2 = getGridElement().getRow(2); + GridCellElement cell3_2 = getGridElement().getCell(3, 2); + + Assert.assertTrue(hasCssClass(row2, "row2")); + Assert.assertTrue(hasCssClass(cell3_2, "Column_2")); + + // Disable the generator and check again + selectRowStyleNameGenerator(GridBasicFeatures.ROW_STYLE_GENERATOR_NONE); + selectCellStyleNameGenerator(GridBasicFeatures.CELL_STYLE_GENERATOR_NONE); + + Assert.assertFalse(hasCssClass(row2, "row2")); + Assert.assertFalse(hasCssClass(cell3_2, "Column_2")); + } + + @Test + public void testChangeStyleNameGenerator() throws Exception { + openTestURL(); + + selectRowStyleNameGenerator(GridBasicFeatures.ROW_STYLE_GENERATOR_ROW_NUMBERS_FOR_3_OF_4); + selectCellStyleNameGenerator(GridBasicFeatures.CELL_STYLE_GENERATOR_SPECIAL); + + // Just verify that change was effective + GridRowElement row2 = getGridElement().getRow(2); + GridCellElement cell3_2 = getGridElement().getCell(3, 2); + + Assert.assertTrue(hasCssClass(row2, "row2")); + Assert.assertTrue(hasCssClass(cell3_2, "Column_2")); + + // Change the generator and check again + selectRowStyleNameGenerator(GridBasicFeatures.ROW_STYLE_GENERATOR_NONE); + selectCellStyleNameGenerator(GridBasicFeatures.CELL_STYLE_GENERATOR_PROPERTY_TO_STRING); + + // Old styles removed? + Assert.assertFalse(hasCssClass(row2, "row2")); + Assert.assertFalse(hasCssClass(cell3_2, "Column_2")); + + // New style present? + Assert.assertTrue(hasCssClass(cell3_2, "Column-2")); + } + + @Test + public void testCellStyleGeneratorWithSelectionColumn() { + setDebug(true); + openTestURL(); + selectMenuPath("Component", "State", "Selection mode", "multi"); + + selectCellStyleNameGenerator(GridBasicFeatures.CELL_STYLE_GENERATOR_SPECIAL); + + assertFalse("Error notification was present", + isElementPresent(NotificationElement.class)); + } + + private void selectRowStyleNameGenerator(String name) { + selectMenuPath("Component", "State", "Row style generator", name); + } + + private void selectCellStyleNameGenerator(String name) { + selectMenuPath("Component", "State", "Cell style generator", name); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java new file mode 100644 index 0000000000..0218fffe61 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridEditorTest.java @@ -0,0 +1,259 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.GridElement.GridEditorElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridEditorTest extends GridBasicFeaturesTest { + + private static final String[] EDIT_ITEM_5 = new String[] { "Component", + "Editor", "Edit item 5" }; + private static final String[] EDIT_ITEM_100 = new String[] { "Component", + "Editor", "Edit item 100" }; + private static final String[] TOGGLE_EDIT_ENABLED = new String[] { + "Component", "Editor", "Enabled" }; + + @Before + public void setUp() { + setDebug(true); + openTestURL(); + selectMenuPath(TOGGLE_EDIT_ENABLED); + } + + @Test + public void testProgrammaticOpeningClosing() { + selectMenuPath(EDIT_ITEM_5); + assertEditorOpen(); + + selectMenuPath("Component", "Editor", "Cancel edit"); + assertEditorClosed(); + } + + @Test + public void testProgrammaticOpeningWhenDisabled() { + selectMenuPath(TOGGLE_EDIT_ENABLED); + selectMenuPath(EDIT_ITEM_5); + assertEditorClosed(); + boolean thrown = logContainsText("Exception occured, java.lang.IllegalStateException"); + assertTrue("IllegalStateException thrown", thrown); + } + + @Test + public void testDisablingWhileOpen() { + selectMenuPath(EDIT_ITEM_5); + selectMenuPath(TOGGLE_EDIT_ENABLED); + assertEditorOpen(); + boolean thrown = logContainsText("Exception occured, java.lang.IllegalStateException"); + assertTrue("IllegalStateException thrown", thrown); + } + + @Test + public void testProgrammaticOpeningWithScroll() { + selectMenuPath(EDIT_ITEM_100); + assertEditorOpen(); + } + + @Test(expected = NoSuchElementException.class) + public void testVerticalScrollLocking() { + selectMenuPath(EDIT_ITEM_5); + getGridElement().getCell(200, 0); + } + + @Test + public void testKeyboardOpeningClosing() { + + getGridElement().getCell(4, 0).click(); + assertEditorClosed(); + + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + assertEditorOpen(); + + new Actions(getDriver()).sendKeys(Keys.ESCAPE).perform(); + assertEditorClosed(); + + // Disable Editor + selectMenuPath(TOGGLE_EDIT_ENABLED); + getGridElement().getCell(5, 0).click(); + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + assertEditorClosed(); + } + + @Test + public void testComponentBinding() { + selectMenuPath(EDIT_ITEM_100); + + List<WebElement> widgets = getEditorWidgets(); + assertEquals("Number of widgets", GridBasicFeatures.COLUMNS, + widgets.size()); + + assertEquals("(100, 0)", widgets.get(0).getAttribute("value")); + assertEquals("(100, 1)", widgets.get(1).getAttribute("value")); + assertEquals("(100, 2)", widgets.get(2).getAttribute("value")); + assertEquals("<b>100</b>", widgets.get(9).getAttribute("value")); + } + + @Test + public void testSave() { + selectMenuPath(EDIT_ITEM_100); + + WebElement textField = getEditorWidgets().get(0); + + textField.click(); + + textField.sendKeys(" changed"); + + WebElement saveButton = getEditor().findElement( + By.className("v-grid-editor-save")); + + saveButton.click(); + + assertEquals("(100, 0) changed", getGridElement().getCell(100, 0) + .getText()); + } + + @Test + public void testProgrammaticSave() { + selectMenuPath(EDIT_ITEM_100); + + WebElement textField = getEditorWidgets().get(0); + + textField.click(); + + textField.sendKeys(" changed"); + + selectMenuPath("Component", "Editor", "Save"); + + assertEquals("(100, 0) changed", getGridElement().getCell(100, 0) + .getText()); + } + + private void assertEditorOpen() { + assertNotNull("Editor is supposed to be open", getEditor()); + assertEquals("Unexpected number of widgets", GridBasicFeatures.COLUMNS, + getEditorWidgets().size()); + } + + private void assertEditorClosed() { + assertNull("Editor is supposed to be closed", getEditor()); + } + + private List<WebElement> getEditorWidgets() { + assertNotNull(getEditor()); + return getEditor().findElements(By.className("v-textfield")); + + } + + @Test + public void testInvalidEdition() { + selectMenuPath(EDIT_ITEM_5); + assertFalse(logContainsText("Exception occured, java.lang.IllegalStateException")); + + GridEditorElement editor = getGridElement().getEditor(); + + WebElement intField = editor.getField(7); + intField.clear(); + intField.sendKeys("banana phone"); + editor.save(); + assertTrue( + "No exception on invalid value.", + logContainsText("Exception occured, com.vaadin.data.fieldgroup.FieldGroup$CommitException: Commit failed")); + editor.cancel(); + + selectMenuPath(EDIT_ITEM_100); + assertFalse("Exception should not exist", + isElementPresent(NotificationElement.class)); + } + + @Test + public void testNoScrollAfterEditByAPI() { + int originalScrollPos = getGridVerticalScrollPos(); + + selectMenuPath(EDIT_ITEM_5); + + scrollGridVerticallyTo(100); + assertEquals("Grid shouldn't scroll vertically while editing", + originalScrollPos, getGridVerticalScrollPos()); + } + + @Test + public void testNoScrollAfterEditByMouse() { + int originalScrollPos = getGridVerticalScrollPos(); + + GridCellElement cell_5_0 = getGridElement().getCell(5, 0); + new Actions(getDriver()).doubleClick(cell_5_0).perform(); + + scrollGridVerticallyTo(100); + assertEquals("Grid shouldn't scroll vertically while editing", + originalScrollPos, getGridVerticalScrollPos()); + } + + @Test + public void testNoScrollAfterEditByKeyboard() { + int originalScrollPos = getGridVerticalScrollPos(); + + GridCellElement cell_5_0 = getGridElement().getCell(5, 0); + cell_5_0.click(); + new Actions(getDriver()).sendKeys(Keys.ENTER).perform(); + + scrollGridVerticallyTo(100); + assertEquals("Grid shouldn't scroll vertically while editing", + originalScrollPos, getGridVerticalScrollPos()); + } + + @Test + public void testEditorInDisabledGrid() { + int originalScrollPos = getGridVerticalScrollPos(); + + selectMenuPath(EDIT_ITEM_5); + assertEditorOpen(); + + selectMenuPath("Component", "State", "Enabled"); + assertEditorOpen(); + + GridEditorElement editor = getGridElement().getEditor(); + editor.save(); + assertEditorOpen(); + + editor.cancel(); + assertEditorOpen(); + + selectMenuPath("Component", "State", "Enabled"); + + scrollGridVerticallyTo(100); + assertEquals("Grid shouldn't scroll vertically while editing", + originalScrollPos, getGridVerticalScrollPos()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridItemClickTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridItemClickTest.java new file mode 100644 index 0000000000..57fc56c995 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridItemClickTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridItemClickTest extends GridBasicFeaturesTest { + + @Test + public void testItemClick() { + openTestURL(); + + selectMenuPath("Component", "State", "ItemClickListener"); + + GridCellElement cell = getGridElement().getCell(3, 2); + new Actions(getDriver()).moveToElement(cell).click().perform(); + + assertTrue("No click in log", logContainsText(itemClickOn(3, 2, false))); + } + + @Test + public void testItemDoubleClick() { + openTestURL(); + + selectMenuPath("Component", "State", "ItemClickListener"); + + GridCellElement cell = getGridElement().getCell(3, 2); + new Actions(getDriver()).moveToElement(cell).doubleClick().perform(); + + assertTrue("No double click in log", + logContainsText(itemClickOn(3, 2, true))); + } + + private String itemClickOn(int row, int column, boolean dblClick) { + return "Item " + (dblClick ? "double " : "") + "click on Column " + + column + ", item " + row; + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridKeyboardNavigationTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridKeyboardNavigationTest.java new file mode 100644 index 0000000000..3f2e82793b --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridKeyboardNavigationTest.java @@ -0,0 +1,221 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridKeyboardNavigationTest extends GridBasicFeaturesTest { + + @Test + public void testCellFocusOnClick() { + openTestURL(); + + GridElement grid = getGridElement(); + assertTrue("Body cell 0, 0 is not focused on init.", grid.getCell(0, 0) + .isFocused()); + grid.getCell(5, 2).click(); + assertFalse("Body cell 0, 0 was still focused after clicking", grid + .getCell(0, 0).isFocused()); + assertTrue("Body cell 5, 2 is not focused after clicking", grid + .getCell(5, 2).isFocused()); + } + + @Test + public void testCellNotFocusedWhenRendererHandlesEvent() { + openTestURL(); + + GridElement grid = getGridElement(); + assertTrue("Body cell 0, 0 is not focused on init.", grid.getCell(0, 0) + .isFocused()); + grid.getHeaderCell(0, 3).click(); + assertFalse("Body cell 0, 0 is focused after click on header.", grid + .getCell(0, 0).isFocused()); + assertTrue("Header cell 0, 3 is not focused after click on header.", + grid.getHeaderCell(0, 3).isFocused()); + } + + @Test + public void testSimpleKeyboardNavigation() { + openTestURL(); + + GridElement grid = getGridElement(); + grid.getCell(0, 0).click(); + + new Actions(getDriver()).sendKeys(Keys.ARROW_DOWN).perform(); + assertTrue("Body cell 1, 0 is not focused after keyboard navigation.", + grid.getCell(1, 0).isFocused()); + + new Actions(getDriver()).sendKeys(Keys.ARROW_RIGHT).perform(); + assertTrue("Body cell 1, 1 is not focused after keyboard navigation.", + grid.getCell(1, 1).isFocused()); + + int i; + for (i = 1; i < 40; ++i) { + new Actions(getDriver()).sendKeys(Keys.ARROW_DOWN).perform(); + } + + assertFalse("Grid has not scrolled with cell focus", + isElementPresent(By.xpath("//td[text() = '(0, 0)']"))); + assertTrue("Cell focus is not visible", + isElementPresent(By.xpath("//td[text() = '(" + i + ", 0)']"))); + assertTrue("Body cell " + i + ", 1 is not focused", grid.getCell(i, 1) + .isFocused()); + } + + @Test + public void testNavigateFromHeaderToBody() { + openTestURL(); + + GridElement grid = getGridElement(); + grid.scrollToRow(300); + new Actions(driver).moveToElement(grid.getHeaderCell(0, 7)).click() + .perform(); + grid.scrollToRow(280); + + assertTrue("Header cell is not focused.", grid.getHeaderCell(0, 7) + .isFocused()); + new Actions(getDriver()).sendKeys(Keys.ARROW_DOWN).perform(); + assertTrue("Body cell 280, 7 is not focused", grid.getCell(280, 7) + .isFocused()); + } + + @Test + public void testNavigationFromFooterToBody() { + openTestURL(); + + selectMenuPath("Component", "Footer", "Visible"); + + GridElement grid = getGridElement(); + grid.scrollToRow(300); + grid.getFooterCell(0, 2).click(); + + assertTrue("Footer cell does not have focus.", grid.getFooterCell(0, 2) + .isFocused()); + new Actions(getDriver()).sendKeys(Keys.ARROW_UP).perform(); + assertTrue("Body cell 300, 2 does not have focus.", grid + .getCell(300, 2).isFocused()); + } + + @Test + public void testNavigateBetweenHeaderAndBodyWithTab() { + openTestURL(); + + GridElement grid = getGridElement(); + grid.getCell(10, 2).click(); + + assertTrue("Body cell 10, 2 does not have focus", grid.getCell(10, 2) + .isFocused()); + new Actions(getDriver()).keyDown(Keys.SHIFT).sendKeys(Keys.TAB) + .keyUp(Keys.SHIFT).perform(); + assertTrue("Header cell 0, 2 does not have focus", + grid.getHeaderCell(0, 2).isFocused()); + new Actions(getDriver()).sendKeys(Keys.TAB).perform(); + assertTrue("Body cell 10, 2 does not have focus", grid.getCell(10, 2) + .isFocused()); + + // Navigate out of the Grid and try to navigate with arrow keys. + new Actions(getDriver()).keyDown(Keys.SHIFT).sendKeys(Keys.TAB) + .sendKeys(Keys.TAB).keyUp(Keys.SHIFT).sendKeys(Keys.ARROW_DOWN) + .perform(); + assertTrue("Header cell 0, 2 does not have focus", + grid.getHeaderCell(0, 2).isFocused()); + } + + @Test + public void testNavigateBetweenFooterAndBodyWithTab() { + openTestURL(); + + selectMenuPath("Component", "Footer", "Visible"); + + GridElement grid = getGridElement(); + grid.getCell(10, 2).click(); + + assertTrue("Body cell 10, 2 does not have focus", grid.getCell(10, 2) + .isFocused()); + new Actions(getDriver()).sendKeys(Keys.TAB).perform(); + assertTrue("Footer cell 0, 2 does not have focus", + grid.getFooterCell(0, 2).isFocused()); + new Actions(getDriver()).keyDown(Keys.SHIFT).sendKeys(Keys.TAB) + .keyUp(Keys.SHIFT).perform(); + assertTrue("Body cell 10, 2 does not have focus", grid.getCell(10, 2) + .isFocused()); + + // Navigate out of the Grid and try to navigate with arrow keys. + new Actions(getDriver()).sendKeys(Keys.TAB).sendKeys(Keys.TAB) + .sendKeys(Keys.ARROW_UP).perform(); + assertTrue("Footer cell 0, 2 does not have focus", + grid.getFooterCell(0, 2).isFocused()); + } + + @Test + public void testHomeEnd() throws Exception { + openTestURL(); + + getGridElement().getCell(100, 2).click(); + + new Actions(getDriver()).sendKeys(Keys.HOME).perform(); + assertTrue("First row is not visible", getGridElement().getCell(0, 2) + .isDisplayed()); + + new Actions(getDriver()).sendKeys(Keys.END).perform(); + assertTrue("Last row cell not visible", + getGridElement().getCell(GridBasicFeatures.ROWS - 1, 2) + .isDisplayed()); + } + + @Test + public void testPageUpPageDown() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Size", "HeightMode Row"); + + getGridElement().getCell(5, 2).click(); + + new Actions(getDriver()).sendKeys(Keys.PAGE_DOWN).perform(); + assertTrue("Row 20 did not become visible", + isElementPresent(By.xpath("//td[text() = '(20, 2)']"))); + + new Actions(getDriver()).sendKeys(Keys.PAGE_DOWN).perform(); + assertTrue("Row 30 did not become visible", + isElementPresent(By.xpath("//td[text() = '(30, 2)']"))); + + assertTrue("Originally focused cell is no longer focused", + getGridElement().getCell(5, 2).isFocused()); + + getGridElement().getCell(50, 2).click(); + + new Actions(getDriver()).sendKeys(Keys.PAGE_UP).perform(); + assertTrue("Row 31 did not become visible", + isElementPresent(By.xpath("//td[text() = '(31, 2)']"))); + + new Actions(getDriver()).sendKeys(Keys.PAGE_UP).perform(); + assertTrue("Row 21 did not become visible", + isElementPresent(By.xpath("//td[text() = '(21, 2)']"))); + + assertTrue("Originally focused cell is no longer focused", + getGridElement().getCell(50, 2).isFocused()); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java new file mode 100644 index 0000000000..a61ed33029 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridMultiSortingTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridMultiSortingTest extends GridBasicFeaturesTest { + + @Override + public List<DesiredCapabilities> getBrowsersToTest() { + List<DesiredCapabilities> browsersToTest = super.getBrowsersToTest(); + /* FireFox and PhantomJS don't know how to press Shift key... */ + browsersToTest.remove(Browser.FIREFOX.getDesiredCapabilities()); + browsersToTest.remove(Browser.PHANTOMJS.getDesiredCapabilities()); + return browsersToTest; + } + + @Test + public void testUserMultiColumnSorting() { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 11", "Column 11 Width", + "Auto"); + + GridCellElement cell = getGridElement().getHeaderCell(0, 11); + new Actions(driver).moveToElement(cell, 5, 5).click().perform(); + new Actions(driver).keyDown(Keys.SHIFT).perform(); + new Actions(driver) + .moveToElement(getGridElement().getHeaderCell(0, 0), 5, 5) + .click().perform(); + new Actions(driver).keyUp(Keys.SHIFT).perform(); + + String prev = getGridElement().getCell(0, 11).getAttribute("innerHTML"); + for (int i = 1; i <= 6; ++i) { + assertEquals("Column 11 should contain same values.", prev, + getGridElement().getCell(i, 11).getAttribute("innerHTML")); + } + + prev = getGridElement().getCell(0, 0).getText(); + for (int i = 1; i <= 6; ++i) { + assertTrue( + "Grid is not sorted by column 0.", + prev.compareTo(getGridElement().getCell(i, 0).getText()) < 0); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java new file mode 100644 index 0000000000..8535efb9ef --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridRowAddRemoveTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import org.junit.Assert; +import org.junit.Test; + +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridRowAddRemoveTest extends GridBasicFeaturesTest { + + @Test + public void addRows_loadAllAtOnce() { + openTestURL(); + + selectMenuPath("Settings", "Clear log"); + selectMenuPath("Component", "Body rows", "Remove all rows"); + selectMenuPath("Component", "Body rows", "Add 18 rows"); + + Assert.assertTrue( + "All added rows should be fetched in the same round trip.", + logContainsText("Requested items 0 - 18")); + } + + @Test + public void removeRows_loadAllAtOnce() { + openTestURL(); + + selectMenuPath("Component", "Size", "HeightMode Row"); + selectMenuPath("Settings", "Clear log"); + selectMenuPath("Component", "Body rows", "Remove 18 first rows"); + + Assert.assertTrue( + "All newly required rows should be fetched in the same round trip.", + logContainsText("Requested items 37 - 55")); + + selectMenuPath("Settings", "Clear log"); + selectMenuPath("Component", "Body rows", "Remove 18 first rows"); + + Assert.assertTrue( + "All newly required rows should be fetched in the same round trip.", + logContainsText("Requested items 37 - 55")); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java new file mode 100644 index 0000000000..3dbf613ba0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSelectionTest.java @@ -0,0 +1,292 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.GridElement.GridRowElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridSelectionTest extends GridBasicFeaturesTest { + + @Test + public void testSelectOnOff() throws Exception { + openTestURL(); + + setSelectionModelMulti(); + + assertFalse("row shouldn't start out as selected", getRow(0) + .isSelected()); + toggleFirstRowSelection(); + assertTrue("row should become selected", getRow(0).isSelected()); + toggleFirstRowSelection(); + assertFalse("row shouldn't remain selected", getRow(0).isSelected()); + } + + @Test + public void testSelectOnScrollOffScroll() throws Exception { + openTestURL(); + + setSelectionModelMulti(); + + assertFalse("row shouldn't start out as selected", getRow(0) + .isSelected()); + toggleFirstRowSelection(); + assertTrue("row should become selected", getRow(0).isSelected()); + + scrollGridVerticallyTo(10000); // make sure the row is out of cache + scrollGridVerticallyTo(0); // scroll it back into view + + assertTrue("row should still be selected when scrolling " + + "back into view", getRow(0).isSelected()); + } + + @Test + public void testSelectScrollOnScrollOff() throws Exception { + openTestURL(); + + setSelectionModelMulti(); + + assertFalse("row shouldn't start out as selected", getRow(0) + .isSelected()); + + scrollGridVerticallyTo(10000); // make sure the row is out of cache + toggleFirstRowSelection(); + + scrollGridVerticallyTo(0); // scroll it back into view + assertTrue("row should still be selected when scrolling " + + "back into view", getRow(0).isSelected()); + + toggleFirstRowSelection(); + assertFalse("row shouldn't remain selected", getRow(0).isSelected()); + } + + @Test + public void testSelectScrollOnOffScroll() throws Exception { + openTestURL(); + + setSelectionModelMulti(); + + assertFalse("row shouldn't start out as selected", getRow(0) + .isSelected()); + + scrollGridVerticallyTo(10000); // make sure the row is out of cache + toggleFirstRowSelection(); + toggleFirstRowSelection(); + + scrollGridVerticallyTo(0); // make sure the row is out of cache + assertFalse("row shouldn't be selected when scrolling " + + "back into view", getRow(0).isSelected()); + } + + @Test + public void testSingleSelectionUpdatesFromServer() { + openTestURL(); + setSelectionModelSingle(); + + GridElement grid = getGridElement(); + assertFalse("First row was selected from start", grid.getRow(0) + .isSelected()); + toggleFirstRowSelection(); + assertTrue("First row was not selected.", getRow(0).isSelected()); + assertTrue("Selection event was not correct", + logContainsText("Added 0, Removed none")); + grid.getCell(5, 0).click(); + assertTrue("Fifth row was not selected.", getRow(5).isSelected()); + assertFalse("First row was still selected.", getRow(0).isSelected()); + assertTrue("Selection event was not correct", + logContainsText("Added 5, Removed 0")); + grid.getCell(0, 6).click(); + assertTrue("Selection event was not correct", + logContainsText("Added 0, Removed 5")); + toggleFirstRowSelection(); + assertTrue("Selection event was not correct", + logContainsText("Added none, Removed 0")); + assertFalse("First row was still selected.", getRow(0).isSelected()); + assertFalse("Fifth row was still selected.", getRow(5).isSelected()); + + grid.scrollToRow(600); + grid.getCell(595, 3).click(); + assertTrue("Row 595 was not selected.", getRow(595).isSelected()); + assertTrue("Selection event was not correct", + logContainsText("Added 595, Removed none")); + toggleFirstRowSelection(); + assertFalse("Row 595 was still selected.", getRow(595).isSelected()); + assertTrue("First row was not selected.", getRow(0).isSelected()); + assertTrue("Selection event was not correct", + logContainsText("Added 0, Removed 595")); + } + + @Test + public void testKeyboardSelection() { + openTestURL(); + setSelectionModelMulti(); + + GridElement grid = getGridElement(); + grid.getCell(3, 1).click(); + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); + + assertTrue("Grid row 3 was not selected with space key.", grid + .getRow(3).isSelected()); + + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); + + assertTrue("Grid row 3 was not deselected with space key.", !grid + .getRow(3).isSelected()); + + grid.scrollToRow(500); + + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); + + assertTrue("Grid row 3 was not selected with space key.", grid + .getRow(3).isSelected()); + } + + @Test + public void testKeyboardWithSingleSelection() { + openTestURL(); + setSelectionModelSingle(); + + GridElement grid = getGridElement(); + grid.getCell(3, 1).click(); + + assertTrue("Grid row 3 was not selected with clicking.", grid.getRow(3) + .isSelected()); + + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); + + assertTrue("Grid row 3 was not deselected with space key.", !grid + .getRow(3).isSelected()); + + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); + + assertTrue("Grid row 3 was not selected with space key.", grid + .getRow(3).isSelected()); + + grid.scrollToRow(500); + + new Actions(getDriver()).sendKeys(Keys.SPACE).perform(); + + assertTrue("Grid row 3 was not deselected with space key.", !grid + .getRow(3).isSelected()); + } + + @Test + public void testSelectAllCheckbox() { + openTestURL(); + + setSelectionModelMulti(); + GridCellElement header = getGridElement().getHeaderCell(0, 0); + + assertTrue("No checkbox", header.isElementPresent(By.tagName("input"))); + header.findElement(By.tagName("input")).click(); + + for (int i = 0; i < GridBasicFeatures.ROWS; i += 100) { + assertTrue("Row " + i + " was not selected.", getGridElement() + .getRow(i).isSelected()); + } + + header.findElement(By.tagName("input")).click(); + assertFalse("Row 100 was still selected", getGridElement().getRow(100) + .isSelected()); + } + + @Test + public void testSelectAllAndSort() { + openTestURL(); + + setSelectionModelMulti(); + GridCellElement header = getGridElement().getHeaderCell(0, 0); + + header.findElement(By.tagName("input")).click(); + + getGridElement().getHeaderCell(0, 1).click(); + + WebElement selectionBox = getGridElement().getCell(4, 0).findElement( + By.tagName("input")); + selectionBox.click(); + selectionBox.click(); + + assertFalse( + "Exception occured on row reselection.", + logContainsText("Exception occured, java.lang.IllegalStateException: No item id for key 101 found.")); + } + + @Test + public void testSelectAllCheckboxWhenChangingModels() { + openTestURL(); + + GridCellElement header; + header = getGridElement().getHeaderCell(0, 0); + assertFalse( + "Check box shouldn't have been in header for None Selection Model", + header.isElementPresent(By.tagName("input"))); + + setSelectionModelMulti(); + header = getGridElement().getHeaderCell(0, 0); + assertTrue("Multi Selection Model should have select all checkbox", + header.isElementPresent(By.tagName("input"))); + + setSelectionModelSingle(); + header = getGridElement().getHeaderCell(0, 0); + assertFalse( + "Check box shouldn't have been in header for Single Selection Model", + header.isElementPresent(By.tagName("input"))); + + // Single selection model shouldn't have selection column to begin with + assertFalse( + "Selection columnn shouldn't have been in grid for Single Selection Model", + getGridElement().getCell(0, 1).isElementPresent( + By.tagName("input"))); + + setSelectionModelNone(); + header = getGridElement().getHeaderCell(0, 0); + assertFalse( + "Check box shouldn't have been in header for None Selection Model", + header.isElementPresent(By.tagName("input"))); + + } + + private void setSelectionModelMulti() { + selectMenuPath("Component", "State", "Selection mode", "multi"); + } + + private void setSelectionModelSingle() { + selectMenuPath("Component", "State", "Selection mode", "single"); + } + + private void setSelectionModelNone() { + selectMenuPath("Component", "State", "Selection mode", "none"); + } + + private void toggleFirstRowSelection() { + selectMenuPath("Component", "Body rows", "Select first row"); + } + + private GridRowElement getRow(int i) { + return getGridElement().getRow(i); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java new file mode 100644 index 0000000000..7e805595c6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridSortingTest.java @@ -0,0 +1,375 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import com.vaadin.shared.data.sort.SortDirection; +import com.vaadin.testbench.By; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.tests.annotations.TestCategory; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +@TestCategory("grid") +public class GridSortingTest extends GridBasicFeaturesTest { + + private static class SortInfo { + public final int sortOrder; + public final SortDirection sortDirection; + + private SortInfo(int sortOrder, SortDirection sortDirection) { + this.sortOrder = sortOrder; + this.sortDirection = sortDirection; + } + } + + private static class SortInfoWithColumn extends SortInfo { + public final int columnIndex; + + private SortInfoWithColumn(int columnIndex, int sortOrder, + SortDirection sortDirection) { + super(sortOrder, sortDirection); + this.columnIndex = columnIndex; + } + } + + private static SortInfo _(int sortOrder, SortDirection sortDirection) { + return new SortInfo(sortOrder, sortDirection); + } + + private static SortInfoWithColumn _(int columnIndex, int sortOrder, + SortDirection sortDirection) { + return new SortInfoWithColumn(columnIndex, sortOrder, sortDirection); + } + + @Test + public void testProgrammaticSorting() throws Exception { + openTestURL(); + + // Sorting by column 9 is sorting by row index that is represented as a + // String. + // First cells for first 3 rows are (9, 0), (99, 0) and (999, 0) + sortBy("Column 9, DESC"); + assertLastSortIsUserOriginated(false); + + // Verify that programmatic sorting calls are identified as originating + // from API + assertColumnsAreSortedAs(_(9, 1, SortDirection.DESCENDING)); + + String row = ""; + for (int i = 0; i < 3; ++i) { + row += "9"; + String expected = "(" + row + ", 0)"; + String cellValue = getGridElement().getCell(i, 0).getText(); + assertEquals("Grid is not sorted by Column 9 " + + "using descending direction.", expected, cellValue); + } + + // Column 10 is random numbers from Random with seed 13334 + sortBy("Column 10, ASC"); + + assertFalse("Column 9 should no longer have the sort-desc stylename", + getGridElement().getHeaderCell(0, 9).getAttribute("class") + .contains("sort-desc")); + + assertColumnsAreSortedAs(_(10, 1, SortDirection.ASCENDING)); + + for (int i = 0; i < 5; ++i) { + Integer firstRow = Integer.valueOf(getGridElement().getCell(i + 1, + 10).getText()); + Integer secondRow = Integer.valueOf(getGridElement().getCell(i, 10) + .getText()); + assertGreater("Grid is not sorted by Column 10 using" + + " ascending direction", firstRow, secondRow); + + } + + // Column 7 is row index as a number. Last three row are original rows + // 2, 1 and 0. + sortBy("Column 7, DESC"); + for (int i = 0; i < 3; ++i) { + String expected = "(" + i + ", 0)"; + String cellContent = getGridElement().getCell( + GridBasicFeatures.ROWS - (i + 1), 0).getText(); + assertEquals("Grid is not sorted by Column 7 using " + + "descending direction", expected, cellContent); + } + + assertFalse("Column 10 should no longer have the sort-asc stylename", + getGridElement().getHeaderCell(0, 10).getAttribute("class") + .contains("sort-asc")); + + assertColumnsAreSortedAs(_(7, 1, SortDirection.DESCENDING)); + } + + @Test + public void testMouseSorting() throws Exception { + setDebug(true); + openTestURL(); + + GridElement grid = getGridElement(); + + selectMenuPath("Component", "Columns", "Column 9", "Column 9 Width", + "Auto"); + + // Sorting by column 9 is sorting by row index that is represented as a + // String. + + // Click header twice to sort descending + GridCellElement header = grid.getHeaderCell(0, 9); + header.click(); + assertLastSortIsUserOriginated(true); + + assertColumnsAreSortedAs(_(9, 1, SortDirection.ASCENDING)); + grid.getHeaderCell(0, 9).click(); + assertColumnsAreSortedAs(_(9, 1, SortDirection.DESCENDING)); + + // First cells for first 3 rows are (9, 0), (99, 0) and (999, 0) + String row = ""; + for (int i = 0; i < 3; ++i) { + row += "9"; + String expected = "(" + row + ", 0)"; + String actual = grid.getCell(i, 0).getText(); + assertEquals("Grid is not sorted by Column 9" + + " using descending direction.", expected, actual); + } + + selectMenuPath("Component", "Columns", "Column 10", "Column 10 Width", + "Auto"); + // Column 10 is random numbers from Random with seed 13334 + // Click header to sort ascending + grid.getHeaderCell(0, 10).click(); + assertColumnsAreSortedAs(_(10, 1, SortDirection.ASCENDING)); + + for (int i = 0; i < 5; ++i) { + Integer firstRow = Integer.valueOf(grid.getCell(i + 1, 10) + .getText()); + Integer secondRow = Integer.valueOf(grid.getCell(i, 10).getText()); + assertGreater( + "Grid is not sorted by Column 10 using ascending direction", + firstRow, secondRow); + + } + + selectMenuPath("Component", "Columns", "Column 7", "Column 7 Width", + "Auto"); + // Column 7 is row index as a number. Last three row are original rows + // 2, 1 and 0. + // Click header twice to sort descending + grid.getHeaderCell(0, 7).click(); + assertColumnsAreSortedAs(_(7, 1, SortDirection.ASCENDING)); + grid.getHeaderCell(0, 7).click(); + assertColumnsAreSortedAs(_(7, 1, SortDirection.DESCENDING)); + + for (int i = 0; i < 3; ++i) { + assertEquals( + "Grid is not sorted by Column 7 using descending direction", + "(" + i + ", 0)", + grid.getCell(GridBasicFeatures.ROWS - (i + 1), 0).getText()); + } + + } + + private void sendKey(Keys seq) { + new Actions(getDriver()).sendKeys(seq).perform(); + } + + private void holdKey(Keys key) { + new Actions(getDriver()).keyDown(key).perform(); + } + + private void releaseKey(Keys key) { + new Actions(getDriver()).keyUp(key).perform(); + } + + @Test + public void testKeyboardSorting() { + openTestURL(); + + /* + * We can't click on the header directly, since it will sort the header + * immediately. We need to focus some other column first, and only then + * navigate there. + */ + getGridElement().getCell(0, 0).click(); + sendKey(Keys.ARROW_UP); + + // Sort ASCENDING on first column + sendKey(Keys.ENTER); + assertLastSortIsUserOriginated(true); + assertColumnsAreSortedAs(_(1, SortDirection.ASCENDING)); + + // Move to next column + sendKey(Keys.RIGHT); + + // Add this column to the existing sorting group + holdKey(Keys.SHIFT); + sendKey(Keys.ENTER); + releaseKey(Keys.SHIFT); + assertColumnsAreSortedAs(_(1, SortDirection.ASCENDING), + _(2, SortDirection.ASCENDING)); + + // Move to next column + sendKey(Keys.RIGHT); + + // Add a third column to the sorting group + holdKey(Keys.SHIFT); + sendKey(Keys.ENTER); + releaseKey(Keys.SHIFT); + assertColumnsAreSortedAs(_(1, SortDirection.ASCENDING), + _(2, SortDirection.ASCENDING), _(3, SortDirection.ASCENDING)); + + // Move back to the second column + sendKey(Keys.LEFT); + + // Change sort direction of the second column to DESCENDING + holdKey(Keys.SHIFT); + sendKey(Keys.ENTER); + releaseKey(Keys.SHIFT); + assertColumnsAreSortedAs(_(1, SortDirection.ASCENDING), + _(2, SortDirection.DESCENDING), _(3, SortDirection.ASCENDING)); + + // Move back to the third column + sendKey(Keys.RIGHT); + + // Set sorting to third column, ASCENDING + sendKey(Keys.ENTER); + assertColumnsAreSortedAs(_(2, 1, SortDirection.ASCENDING)); + + // Move to the fourth column + sendKey(Keys.RIGHT); + + // Make sure that single-column sorting also works as expected + sendKey(Keys.ENTER); + assertColumnsAreSortedAs(_(3, 1, SortDirection.ASCENDING)); + + } + + private void assertColumnsAreSortedAs(SortInfoWithColumn... sortInfos) { + for (SortInfoWithColumn sortInfo : sortInfos) { + assertSort(sortInfo, sortInfo.columnIndex, + onlyOneColumnIsSorted(sortInfos)); + } + } + + /** + * @param sortDirections + * <code>null</code> if not interested in that index, otherwise a + * direction that the column needs to be sorted as + */ + private void assertColumnsAreSortedAs(SortInfo... sortInfos) { + for (int column = 0; column < sortInfos.length; column++) { + SortInfo sortInfo = sortInfos[column]; + assertSort(sortInfo, column, onlyOneColumnIsSorted(sortInfos)); + } + } + + private void assertSort(SortInfo sortInfo, int column, + boolean onlyOneColumnIsSorted) { + if (sortInfo == null) { + return; + } + + GridCellElement headerCell = getGridElement().getHeaderCell(0, column); + String classValue = headerCell.getAttribute("class"); + + boolean isSortedAscending = sortInfo.sortDirection == SortDirection.ASCENDING + && classValue.contains("sort-asc"); + boolean isSortedDescending = sortInfo.sortDirection == SortDirection.DESCENDING + && classValue.contains("sort-desc"); + + if (isSortedAscending || isSortedDescending) { + String sortOrderAttribute = headerCell.getAttribute("sort-order"); + + if (sortOrderAttribute == null) { + if (!(sortInfo.sortOrder == 1 && onlyOneColumnIsSorted)) { + fail("missing sort-order element attribute from column " + + column); + } + } else { + assertEquals("sort order was not as expected", + String.valueOf(sortInfo.sortOrder), sortOrderAttribute); + } + } else { + fail("column index " + column + " was not sorted as " + + sortInfo.sortDirection + " (class: " + classValue + ")"); + } + } + + private static boolean onlyOneColumnIsSorted(SortInfo[] sortInfos) { + + boolean foundSortedColumn = false; + for (SortInfo sortInfo : sortInfos) { + if (sortInfo == null) { + continue; + } + + if (!foundSortedColumn) { + foundSortedColumn = true; + } else { + // two columns were sorted + return false; + } + } + return foundSortedColumn; + } + + private void sortBy(String column) { + selectMenuPath("Component", "State", "Sort by column", column); + } + + private void assertLastSortIsUserOriginated(boolean isUserOriginated) { + List<WebElement> userOriginatedMessages = getDriver() + .findElements( + By.xpath("//*[contains(text(),'SortOrderChangeEvent: isUserOriginated')]")); + + Collections.sort(userOriginatedMessages, new Comparator<WebElement>() { + @Override + public int compare(WebElement o1, WebElement o2) { + return o1.getText().compareTo(o2.getText()); + } + }); + + String newestEntry = userOriginatedMessages.get( + userOriginatedMessages.size() - 1).getText(); + + String[] parts = newestEntry.split(" "); + boolean wasUserOriginated = Boolean + .parseBoolean(parts[parts.length - 1]); + if (isUserOriginated) { + assertTrue("expected the sort to be user originated, but wasn't", + wasUserOriginated); + } else { + assertFalse( + "expected the sort not to be user originated, but it was", + wasUserOriginated); + } + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStaticSectionComponentTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStaticSectionComponentTest.java new file mode 100644 index 0000000000..2fbaa58cab --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStaticSectionComponentTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridStaticSectionComponentTest extends GridBasicFeaturesTest { + + @Test + public void testNativeButtonInHeader() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Columns", "Column 1", "Header Type", + "Widget Header"); + + getGridElement().$(ButtonElement.class).first().click(); + + assertTrue("Button click should be logged", + logContainsText("Button clicked!")); + } + + @Test + public void testNativeButtonInFooter() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Footer", "Visible"); + selectMenuPath("Component", "Footer", "Append row"); + selectMenuPath("Component", "Columns", "Column 1", "Footer Type", + "Widget Footer"); + + getGridElement().$(ButtonElement.class).first().click(); + + assertTrue("Button click should be logged", + logContainsText("Button clicked!")); + } + + @Test + public void testRemoveComponentFromHeader() throws Exception { + openTestURL(); + selectMenuPath("Component", "Columns", "Column 1", "Header Type", + "Widget Header"); + selectMenuPath("Component", "Columns", "Column 1", "Header Type", + "Text Header"); + assertTrue("No notifications should've been shown", + !$(NotificationElement.class).exists()); + assertEquals("Header should've been reverted back to text header", + "text header", getGridElement().getHeaderCell(0, 1).getText() + .toLowerCase()); + } + +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java new file mode 100644 index 0000000000..08f903b3fe --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/GridStructureTest.java @@ -0,0 +1,485 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.List; + +import org.junit.Test; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.By; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.testbench.elements.GridElement.GridCellElement; +import com.vaadin.testbench.elements.NotificationElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeatures; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class GridStructureTest extends GridBasicFeaturesTest { + + @Test + public void testRemovingAllColumns() { + setDebug(true); + openTestURL(); + for (int i = 0; i < GridBasicFeatures.COLUMNS; ++i) { + selectMenuPath("Component", "Columns", "Column " + i, + "Add / Remove"); + assertFalse(isElementPresent(NotificationElement.class)); + } + + assertEquals("Headers still visible.", 0, getGridHeaderRowCells() + .size()); + } + + @Test + public void testRemoveAndAddColumn() { + setDebug(true); + openTestURL(); + + assertEquals("column 0", getGridElement().getHeaderCell(0, 0).getText() + .toLowerCase()); + selectMenuPath("Component", "Columns", "Column 0", "Add / Remove"); + assertEquals("column 1", getGridElement().getHeaderCell(0, 0).getText() + .toLowerCase()); + selectMenuPath("Component", "Columns", "Column 0", "Add / Remove"); + // Column 0 is appended to the end of grid + assertEquals("column 0", getGridElement().getHeaderCell(0, 11) + .getText().toLowerCase()); + } + + @Test + public void testRemovingColumn() throws Exception { + openTestURL(); + + // Column 0 should be visible + List<TestBenchElement> cells = getGridHeaderRowCells(); + assertEquals("column 0", cells.get(0).getText().toLowerCase()); + + // Hide column 0 + selectMenuPath("Component", "Columns", "Column 0", "Add / Remove"); + + // Column 1 should now be the first cell + cells = getGridHeaderRowCells(); + assertEquals("column 1", cells.get(0).getText().toLowerCase()); + } + + @Test + public void testDataLoadingAfterRowRemoval() throws Exception { + openTestURL(); + + // Remove columns 2,3,4 + selectMenuPath("Component", "Columns", "Column 2", "Add / Remove"); + selectMenuPath("Component", "Columns", "Column 3", "Add / Remove"); + selectMenuPath("Component", "Columns", "Column 4", "Add / Remove"); + + // Scroll so new data is lazy loaded + scrollGridVerticallyTo(1000); + + // Let lazy loading do its job + sleep(1000); + + // Check that row is loaded + assertThat(getGridElement().getCell(11, 0).getText(), not("...")); + } + + @Test + public void testFreezingColumn() throws Exception { + openTestURL(); + + // Freeze column 1 + selectMenuPath("Component", "State", "Frozen column count", "1"); + + WebElement cell = getGridElement().getCell(0, 0); + assertTrue(cell.getAttribute("class").contains("frozen")); + + cell = getGridElement().getCell(0, 1); + assertFalse(cell.getAttribute("class").contains("frozen")); + } + + @Test + public void testInitialColumnWidths() throws Exception { + openTestURL(); + + WebElement cell = getGridElement().getCell(0, 0); + assertEquals(100, cell.getSize().getWidth()); + + cell = getGridElement().getCell(0, 1); + assertEquals(150, cell.getSize().getWidth()); + + cell = getGridElement().getCell(0, 2); + assertEquals(200, cell.getSize().getWidth()); + } + + @Test + public void testColumnWidths() throws Exception { + openTestURL(); + + // Default column width is 100px + WebElement cell = getGridElement().getCell(0, 0); + assertEquals(100, cell.getSize().getWidth()); + + // Set first column to be 200px wide + selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", + "200px"); + + cell = getGridElement().getCell(0, 0); + assertEquals(200, cell.getSize().getWidth()); + + // Set second column to be 150px wide + selectMenuPath("Component", "Columns", "Column 1", "Column 1 Width", + "150px"); + cell = getGridElement().getCell(0, 1); + assertEquals(150, cell.getSize().getWidth()); + + selectMenuPath("Component", "Columns", "Column 0", "Column 0 Width", + "Auto"); + + // since the column 0 was previously 200, it should've shrunk when + // autoresizing. + cell = getGridElement().getCell(0, 0); + assertLessThan("", cell.getSize().getWidth(), 200); + } + + @Test + public void testPrimaryStyleNames() throws Exception { + openTestURL(); + + // v-grid is default primary style namea + assertPrimaryStylename("v-grid"); + + selectMenuPath("Component", "State", "Primary style name", + "v-escalator"); + assertPrimaryStylename("v-escalator"); + + selectMenuPath("Component", "State", "Primary style name", "my-grid"); + assertPrimaryStylename("my-grid"); + + selectMenuPath("Component", "State", "Primary style name", "v-grid"); + assertPrimaryStylename("v-grid"); + } + + /** + * Test that the current view is updated when a server-side container change + * occurs (without scrolling back and forth) + */ + @Test + public void testItemSetChangeEvent() throws Exception { + openTestURL(); + + final org.openqa.selenium.By newRow = By + .xpath("//td[text()='newcell: 0']"); + + assertTrue("Unexpected initial state", !isElementPresent(newRow)); + + selectMenuPath("Component", "Body rows", "Add first row"); + assertTrue("Add row failed", isElementPresent(newRow)); + + selectMenuPath("Component", "Body rows", "Remove first row"); + assertTrue("Remove row failed", !isElementPresent(newRow)); + } + + /** + * Test that the current view is updated when a property's value is reflect + * to the client, when the value is modified server-side. + */ + @Test + public void testPropertyValueChangeEvent() throws Exception { + openTestURL(); + + assertEquals("Unexpected cell initial state", "(0, 0)", + getGridElement().getCell(0, 0).getText()); + + selectMenuPath("Component", "Body rows", + "Modify first row (getItemProperty)"); + assertEquals("(First) modification with getItemProperty failed", + "modified: 0", getGridElement().getCell(0, 0).getText()); + + selectMenuPath("Component", "Body rows", + "Modify first row (getContainerProperty)"); + assertEquals("(Second) modification with getItemProperty failed", + "modified: Column 0", getGridElement().getCell(0, 0).getText()); + } + + @Test + public void testRemovingAllItems() throws Exception { + openTestURL(); + + selectMenuPath("Component", "Body rows", "Remove all rows"); + + assertEquals(0, getGridElement().findElement(By.tagName("tbody")) + .findElements(By.tagName("tr")).size()); + } + + @Test + public void testVerticalScrollBarVisibilityWhenEnoughRows() + throws Exception { + openTestURL(); + + assertTrue(verticalScrollbarIsPresent()); + + selectMenuPath("Component", "Body rows", "Remove all rows"); + assertFalse(verticalScrollbarIsPresent()); + + selectMenuPath("Component", "Size", "HeightMode Row"); + selectMenuPath("Component", "Size", "Height by Rows", "2.33 rows"); + selectMenuPath("Component", "Body rows", "Add first row"); + selectMenuPath("Component", "Body rows", "Add first row"); + assertFalse(verticalScrollbarIsPresent()); + + selectMenuPath("Component", "Body rows", "Add first row"); + assertTrue(verticalScrollbarIsPresent()); + } + + @Test + public void testBareItemSetChange() throws Exception { + openTestURL(); + filterSomeAndAssert(); + } + + @Test + public void testBareItemSetChangeRemovingAllRows() throws Exception { + openTestURL(); + selectMenuPath("Component", "Filter", "Add impassable filter"); + assertFalse("A notification shouldn't have been displayed", + $(NotificationElement.class).exists()); + assertTrue("No body cells should've been found", getGridElement() + .getBody().findElements(By.tagName("td")).isEmpty()); + } + + @Test + public void testBareItemSetChangeWithMidScroll() throws Exception { + openTestURL(); + getGridElement().scrollToRow(GridBasicFeatures.ROWS / 2); + filterSomeAndAssert(); + } + + @Test + public void testBareItemSetChangeWithBottomScroll() throws Exception { + openTestURL(); + getGridElement().scrollToRow(GridBasicFeatures.ROWS); + filterSomeAndAssert(); + } + + private void filterSomeAndAssert() { + selectMenuPath("Component", "Filter", "Column 1 starts with \"(23\""); + boolean foundElements = false; + for (int row = 0; row < 100; row++) { + try { + GridCellElement cell = getGridElement().getCell(row, 1); + foundElements = true; + assertTrue("Unexpected cell contents. " + + "Did the ItemSetChange work after all?", cell + .getText().startsWith("(23")); + } catch (NoSuchElementException e) { + assertTrue("No rows were found", foundElements); + return; + } + } + fail("unexpected amount of rows post-filter. Did the ItemSetChange work after all?"); + } + + @Test + public void testRemoveLastColumn() { + setDebug(true); + openTestURL(); + + String columnName = "Column " + (GridBasicFeatures.COLUMNS - 1); + assertTrue(columnName + " was not present in DOM", + isElementPresent(By.xpath("//th[text()='" + columnName + "']"))); + selectMenuPath("Component", "Columns", columnName, "Add / Remove"); + assertFalse(isElementPresent(NotificationElement.class)); + assertFalse(columnName + " was still present in DOM", + isElementPresent(By.xpath("//th[text()='" + columnName + "']"))); + } + + @Test + public void testReverseColumns() { + openTestURL(); + + String[] gridData = new String[GridBasicFeatures.COLUMNS]; + GridElement grid = getGridElement(); + for (int i = 0; i < gridData.length; ++i) { + gridData[i] = grid.getCell(0, i).getAttribute("innerHTML"); + } + + selectMenuPath("Component", "State", "Reverse Grid Columns"); + + // Compare with reversed order + for (int i = 0; i < gridData.length; ++i) { + final int column = gridData.length - 1 - i; + final String newText = grid.getCell(0, column).getAttribute( + "innerHTML"); + assertEquals("Grid contained unexpected values. (0, " + column + + ")", gridData[i], newText); + } + } + + @Test + public void testAddingProperty() { + setDebug(true); + openTestURL(); + + assertNotEquals("property value", getGridElement().getCell(0, 0) + .getText()); + selectMenuPath("Component", "Properties", "Prepend property"); + assertEquals("property value", getGridElement().getCell(0, 0).getText()); + } + + @Test + public void testRemovingAddedProperty() { + openTestURL(); + + assertEquals("(0, 0)", getGridElement().getCell(0, 0).getText()); + assertNotEquals("property value", getGridElement().getCell(0, 0) + .getText()); + + selectMenuPath("Component", "Properties", "Prepend property"); + selectMenuPath("Component", "Properties", "Prepend property"); + + assertNotEquals("property value", getGridElement().getCell(0, 0) + .getText()); + assertEquals("(0, 0)", getGridElement().getCell(0, 0).getText()); + } + + private boolean verticalScrollbarIsPresent() { + return "scroll".equals(getGridVerticalScrollbar().getCssValue( + "overflow-y")); + } + + @Test + public void testAddRowAboveViewport() { + setDebug(true); + openTestURL(); + + GridCellElement cell = getGridElement().getCell(500, 1); + String cellContent = cell.getText(); + selectMenuPath("Component", "Body rows", "Add first row"); + + assertFalse("Error notification was present", + isElementPresent(NotificationElement.class)); + + assertEquals("Grid scrolled unexpectedly", cellContent, cell.getText()); + } + + @Test + public void testRemoveAndAddRowAboveViewport() { + setDebug(true); + openTestURL(); + + GridCellElement cell = getGridElement().getCell(500, 1); + String cellContent = cell.getText(); + selectMenuPath("Component", "Body rows", "Remove first row"); + + assertFalse("Error notification was present after removing row", + isElementPresent(NotificationElement.class)); + + assertEquals("Grid scrolled unexpectedly", cellContent, cell.getText()); + + selectMenuPath("Component", "Body rows", "Add first row"); + + assertFalse("Error notification was present after adding row", + isElementPresent(NotificationElement.class)); + + assertEquals("Grid scrolled unexpectedly", cellContent, cell.getText()); + } + + @Test + public void testScrollAndRemoveAll() { + setDebug(true); + openTestURL(); + + getGridElement().scrollToRow(500); + selectMenuPath("Component", "Body rows", "Remove all rows"); + + assertFalse("Error notification was present after removing all rows", + isElementPresent(NotificationElement.class)); + + assertFalse(getGridElement().isElementPresent(By.vaadin("#cell[0][0]"))); + } + + private void assertPrimaryStylename(String stylename) { + assertTrue(getGridElement().getAttribute("class").contains(stylename)); + + String tableWrapperStyleName = getGridElement().getTableWrapper() + .getAttribute("class"); + assertTrue(tableWrapperStyleName.contains(stylename + "-tablewrapper")); + + String hscrollStyleName = getGridElement().getHorizontalScroller() + .getAttribute("class"); + assertTrue(hscrollStyleName.contains(stylename + "-scroller")); + assertTrue(hscrollStyleName + .contains(stylename + "-scroller-horizontal")); + + String vscrollStyleName = getGridElement().getVerticalScroller() + .getAttribute("class"); + assertTrue(vscrollStyleName.contains(stylename + "-scroller")); + assertTrue(vscrollStyleName.contains(stylename + "-scroller-vertical")); + } + + @Test + public void testScrollPosDoesNotChangeAfterStateChange() { + openTestURL(); + scrollGridVerticallyTo(1000); + int scrollPos = getGridVerticalScrollPos(); + selectMenuPath("Component", "Editor", "Enabled"); + assertEquals("Scroll position should've not have changed", scrollPos, + getGridVerticalScrollPos()); + } + + @Test + public void testReloadPage() throws InterruptedException { + setDebug(true); + openTestURL(); + + reopenTestURL(); + + // After opening the URL Grid can be stuck in a state where it thinks it + // should wait for something that's not going to happen. + testBench().disableWaitForVaadin(); + + // Wait until page is loaded completely. + int count = 0; + while (!isElementPresent(GridElement.class)) { + if (count == 100) { + fail("Reloading page failed"); + } + sleep(100); + ++count; + } + + // Wait a bit more for notification to occur. + sleep(1000); + + assertFalse("Exception occurred when reloading page", + isElementPresent(NotificationElement.class)); + } + + @Test + public void testAddThirdRowToGrid() { + openTestURL(); + selectMenuPath("Component", "Body rows", "Add third row"); + assertFalse(logContainsText("Exception occured")); + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/LoadingIndicatorTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/LoadingIndicatorTest.java new file mode 100644 index 0000000000..b122eb02e9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/server/LoadingIndicatorTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.grid.basicfeatures.server; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; + +import com.vaadin.testbench.elements.GridElement; +import com.vaadin.tests.components.grid.basicfeatures.GridBasicFeaturesTest; + +public class LoadingIndicatorTest extends GridBasicFeaturesTest { + @Test + public void testLoadingIndicator() throws InterruptedException { + setDebug(true); + openTestURL(); + + selectMenuPath("Component", "State", "Container delay", "2000"); + + GridElement gridElement = $(GridElement.class).first(); + + Assert.assertFalse( + "Loading indicator should not be visible before disabling waitForVaadin", + isLoadingIndicatorVisible()); + + testBench().disableWaitForVaadin(); + + // Scroll to a completely new location + gridElement.getCell(200, 1); + + // Wait for loading indicator delay + Thread.sleep(500); + + Assert.assertTrue( + "Loading indicator should be visible when fetching rows that are visible", + isLoadingIndicatorVisible()); + + waitUntilNot(ExpectedConditions.visibilityOfElementLocated(By + .className("v-loading-indicator"))); + + // Scroll so much that more data gets fetched, but not so much that + // missing rows are shown + gridElement.getCell(230, 1); + + // Wait for potentially triggered loading indicator to become visible + Thread.sleep(500); + + Assert.assertFalse( + "Loading indicator should not be visible when fetching rows that are not visible", + isLoadingIndicatorVisible()); + + // Finally verify that there was actually a request going on + Thread.sleep(2000); + + String firstLogRow = getLogRow(0); + Assert.assertTrue( + "Last log message should be number 6: " + firstLogRow, + firstLogRow.startsWith("6. Requested items")); + } + + private boolean isLoadingIndicatorVisible() { + WebElement loadingIndicator = findElement(By + .className("v-loading-indicator")); + if (loadingIndicator == null) { + return false; + } else { + return loadingIndicator.isDisplayed(); + } + + } +} diff --git a/uitest/src/com/vaadin/tests/components/grid/myBeanJsRenderer.js b/uitest/src/com/vaadin/tests/components/grid/myBeanJsRenderer.js new file mode 100644 index 0000000000..5e7bde5ec7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/myBeanJsRenderer.js @@ -0,0 +1,16 @@ +window.com_vaadin_tests_components_grid_MyBeanJSRenderer = function() { + this.init = function(cell) { + cell.element.setAttribute("column", cell.columnIndex); + } + + this.render = function(cell, data) { + cell.element.innerHTML = 'Bean(' + data.integer + ', ' + data.string + ')' + } + + this.getConsumedEvents = function() { return ["click"] }; + + this.onBrowserEvent = function(cell, event) { + cell.element.innerHTML = "Clicked " + cell.rowIndex + " with key " + this.getRowKey(cell.rowIndex) +" at " + event.clientX; + return true; + } +}
\ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticReindeer.java b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticReindeer.java new file mode 100644 index 0000000000..6cf7fb0ded --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticReindeer.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.progressindicator; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ProgressBar; +import com.vaadin.ui.themes.Reindeer; + +@Theme(Reindeer.THEME_NAME) +public class ProgressBarStaticReindeer extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + ProgressBar progressBar = new ProgressBar(); + progressBar.addStyleName(Reindeer.PROGRESSBAR_STATIC); + addComponent(progressBar); + } +} diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticReindeerTest.java b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticReindeerTest.java new file mode 100644 index 0000000000..f1056a640d --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticReindeerTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.progressindicator; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ProgressBarStaticReindeerTest extends MultiBrowserTest { + @Test + public void compareScreenshot() throws Exception { + openTestURL(); + compareScreen("screen"); + } +} diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticRuno.java b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticRuno.java new file mode 100644 index 0000000000..4e1ff7c886 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticRuno.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.progressindicator; + +import com.vaadin.annotations.Theme; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.ProgressBar; +import com.vaadin.ui.themes.Runo; + +@Theme(Runo.THEME_NAME) +public class ProgressBarStaticRuno extends AbstractTestUI { + @Override + protected void setup(VaadinRequest request) { + ProgressBar progressBar = new ProgressBar(); + progressBar.addStyleName(Runo.PROGRESSBAR_STATIC); + addComponent(progressBar); + } +} diff --git a/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticRunoTest.java b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticRunoTest.java new file mode 100644 index 0000000000..751e048694 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/progressindicator/ProgressBarStaticRunoTest.java @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.components.progressindicator; + +import org.junit.Test; + +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ProgressBarStaticRunoTest extends MultiBrowserTest { + @Test + public void compareScreenshot() throws Exception { + openTestURL(); + compareScreen("screen"); + } +} diff --git a/uitest/src/com/vaadin/tests/serialization/NoLayout.java b/uitest/src/com/vaadin/tests/serialization/NoLayout.java new file mode 100644 index 0000000000..8ce8c437a4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/serialization/NoLayout.java @@ -0,0 +1,101 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.serialization; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.server.LayoutDetector; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.JavaScript; + +@Widgetset(TestingWidgetSet.NAME) +public class NoLayout extends AbstractTestUI { + private final LayoutDetector layoutDetector = new LayoutDetector(); + + @Override + protected void setup(VaadinRequest request) { + addComponent(layoutDetector); + + CheckBox uiPolling = new CheckBox("UI polling enabled"); + uiPolling.addValueChangeListener(new ValueChangeListener() { + @Override + public void valueChange(ValueChangeEvent event) { + if (event.getProperty().getValue() == Boolean.TRUE) { + setPollInterval(100); + } else { + setPollInterval(-1); + } + } + }); + addComponent(uiPolling); + + addComponent(new Button("Change regular state", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + event.getButton().setCaption( + String.valueOf(System.currentTimeMillis())); + } + })); + addComponent(new Button("Change @NoLayout state", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + event.getButton().setDescription( + String.valueOf(System.currentTimeMillis())); + } + })); + addComponent(new Button("Do regular RPC", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + JavaScript.eval(""); + } + })); + + addComponent(new Button("Do @NoLayout RPC", new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + layoutDetector.doNoLayoutRpc(); + } + })); + + addComponent(new Button("Update LegacyComponent", + new Button.ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + // Assumes UI is a LegacyComponent + markAsDirty(); + } + })); + } + + @Override + protected String getTestDescription() { + return "Checks which actions trigger a layout phase"; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(12936); + } + +} diff --git a/uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java b/uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java new file mode 100644 index 0000000000..bb312e3f3f --- /dev/null +++ b/uitest/src/com/vaadin/tests/serialization/NoLayoutTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.serialization; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.By; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.CheckBoxElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class NoLayoutTest extends MultiBrowserTest { + @Test + public void testNoLayout() { + openTestURL(); + assertCounts(1, 0); + + $(CheckBoxElement.class).caption("UI polling enabled").first() + .findElement(By.tagName("input")).click(); + + // Toggling check box requires layout + assertCounts(2, 0); + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + // Count should not change even with polling enabled + assertCounts(2, 0); + + // Disable polling + $(CheckBoxElement.class).caption("UI polling enabled").first() + .findElement(By.tagName("input")).click(); + // Toggling checkbox layotus again + assertCounts(3, 0); + + $(ButtonElement.class).caption("Change regular state").first().click(); + // Updating normal state layouts + assertCounts(4, 0); + + $(ButtonElement.class).caption("Change @NoLayout state").first(); + // Updating @NoLayout state does not layout + assertCounts(4, 0); + + $(ButtonElement.class).caption("Do regular RPC").first().click(); + // Doing normal RPC layouts + assertCounts(5, 0); + + $(ButtonElement.class).caption("Do @NoLayout RPC").first().click(); + // Doing @NoLayout RPC does not layout, but updates the RPC count + assertCounts(5, 1); + + $(ButtonElement.class).caption("Update LegacyComponent").first() + .click(); + // Painting LegacyComponent layouts + assertCounts(6, 1); + } + + private void assertCounts(int layoutCount, int rpcCount) { + Assert.assertEquals("Unexpected layout count", layoutCount, + getCount("layoutCount")); + Assert.assertEquals("Unexpected RPC count", rpcCount, + getCount("rpcCount")); + } + + private int getCount(String id) { + return Integer.parseInt(getDriver().findElement(By.id(id)).getText()); + } +} diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java index bb8b34d462..2ac10c161d 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java @@ -44,10 +44,14 @@ import com.vaadin.tests.widgetset.client.SerializerTestState; import com.vaadin.tests.widgetset.client.SimpleTestBean; import com.vaadin.tests.widgetset.server.SerializerTestExtension; +import elemental.json.Json; +import elemental.json.JsonString; +import elemental.json.JsonValue; + @Widgetset("com.vaadin.tests.widgetset.TestingWidgetSet") public class SerializerTest extends AbstractTestUI { - private Log log = new Log(40); + private Log log = new Log(45); @Override protected void setup(VaadinRequest request) { @@ -258,6 +262,12 @@ public class SerializerTest extends AbstractTestUI { rpc.sendDate(new Date(1)); rpc.sendDate(new Date(2013 - 1900, 5 - 1, 31, 11, 12, 13)); + + state.jsonNull = Json.createNull(); + state.jsonString = Json.create("a string"); + state.jsonBoolean = Json.create(false); + rpc.sendJson(Json.create(true), Json.createNull(), Json.create("JSON")); + state.date1 = new Date(1); state.date2 = new Date(2013 - 1900, 5 - 1, 31, 11, 12, 13); @@ -458,6 +468,13 @@ public class SerializerTest extends AbstractTestUI { } @Override + public void sendJson(JsonValue value1, JsonValue value2, + JsonString string) { + log.log("sendJson: " + value1.toJson() + ", " + value2.toJson() + + ", " + string.toJson()); + } + + @Override public void log(String string) { log.log(string); @@ -468,7 +485,7 @@ public class SerializerTest extends AbstractTestUI { @Override protected String getTestDescription() { - return "Test for lots of different cases of encoding and decoding variuos data types"; + return "Test for lots of different cases of encoding and decoding various data types"; } @Override diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java index 1624a89a01..23af74c78b 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java @@ -27,6 +27,9 @@ public class SerializerTestTest extends MultiBrowserTest { openTestURL(); int logRow = 0; + Assert.assertEquals( + "sendJson: {\"b\":false,\"s\":\"JSON\"}, null, \"value\"", + getLogRow(logRow++)); Assert.assertEquals("sendDate: May 31, 2013 8:12:13 AM UTC", getLogRow(logRow++)); Assert.assertEquals("sendDate: January 1, 1970 12:00:00 AM UTC", @@ -77,6 +80,9 @@ public class SerializerTestTest extends MultiBrowserTest { "sendBoolean: false, false, [false, false, true, false, true, true]", getLogRow(logRow++)); Assert.assertEquals("sendBeanSubclass: 43", getLogRow(logRow++)); + Assert.assertEquals("state.jsonBoolean: false", getLogRow(logRow++)); + Assert.assertEquals("state.jsonString: a string", getLogRow(logRow++)); + Assert.assertEquals("state.jsonNull: NULL", getLogRow(logRow++)); Assert.assertEquals( "state.doubleArray: [1.7976931348623157e+308, 5e-324]", getLogRow(logRow++)); diff --git a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml index 2c25c54e04..8a02d91d2c 100644 --- a/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml +++ b/uitest/src/com/vaadin/tests/widgetset/TestingWidgetSet.gwt.xml @@ -4,6 +4,8 @@ <!-- Inherit the DefaultWidgetSet --> <inherits name="com.vaadin.DefaultWidgetSet" /> + <inherits name="com.google.gwt.user.theme.standard.Standard" /> + <replace-with class="com.vaadin.tests.widgetset.client.CustomUIConnector"> <when-type-is class="com.vaadin.client.ui.ui.UIConnector" /> </replace-with> @@ -17,5 +19,9 @@ class="com.vaadin.tests.widgetset.client.MockApplicationConnection"> <when-type-is class="com.vaadin.client.ApplicationConnection" /> </replace-with> + + <generate-with class="com.vaadin.tests.widgetset.rebind.TestWidgetRegistryGenerator"> + <when-type-is class="com.vaadin.tests.widgetset.client.TestWidgetConnector.TestWidgetRegistry" /> + </generate-with> </module> diff --git a/uitest/src/com/vaadin/tests/widgetset/client/BasicExtensionTestConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/BasicExtensionTestConnector.java index 6bd2abec60..86c918536f 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/BasicExtensionTestConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/BasicExtensionTestConnector.java @@ -19,7 +19,6 @@ package com.vaadin.tests.widgetset.client; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Document; import com.vaadin.client.ServerConnector; -import com.vaadin.client.Util; import com.vaadin.client.extensions.AbstractExtensionConnector; import com.vaadin.shared.ui.Connect; import com.vaadin.tests.extensions.BasicExtension; @@ -35,8 +34,8 @@ public class BasicExtensionTestConnector extends AbstractExtensionConnector { } private void appendMessage(String action) { - String message = Util.getSimpleName(this) + action - + Util.getSimpleName(target); + String message = getClass().getSimpleName() + action + + target.getClass().getSimpleName(); DivElement element = Document.get().createDivElement(); element.setInnerText(message); diff --git a/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java index b43da8e27e..7a93f5e360 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/CustomUIConnector.java @@ -18,7 +18,6 @@ package com.vaadin.tests.widgetset.client; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.SpanElement; -import com.vaadin.client.Util; import com.vaadin.client.ui.ui.UIConnector; import com.vaadin.shared.ui.Connect; import com.vaadin.ui.UI; @@ -33,7 +32,7 @@ public class CustomUIConnector extends UIConnector { public void test() { SpanElement span = Document.get().createSpanElement(); span.setInnerText("This is the " - + Util.getSimpleName(CustomUIConnector.this)); + + CustomUIConnector.this.getClass().getSimpleName()); Document.get().getBody().insertFirst(span); } }); diff --git a/uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java new file mode 100644 index 0000000000..e999c83b75 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/LayoutDetectorConnector.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client; + +import com.google.gwt.user.client.ui.HTML; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.client.ui.PostLayoutListener; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.LayoutDetector; + +@Connect(LayoutDetector.class) +public class LayoutDetectorConnector extends AbstractComponentConnector + implements PostLayoutListener { + private int layoutCount = 0; + private int rpcCount = 0; + + @Override + protected void init() { + super.init(); + updateText(); + + registerRpc(NoLayoutRpc.class, new NoLayoutRpc() { + @Override + public void doRpc() { + rpcCount++; + updateText(); + } + }); + } + + @Override + public HTML getWidget() { + return (HTML) super.getWidget(); + } + + @Override + public void postLayout() { + layoutCount++; + updateText(); + } + + private void updateText() { + getWidget().setHTML( + "Layout count: <span id='layoutCount'>" + layoutCount + + "</span><br />RPC count: <span id='rpcCount'>" + + rpcCount + "</span>"); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java b/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java index 4ee5b71387..0da1c6c775 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/MockApplicationConnection.java @@ -18,13 +18,14 @@ package com.vaadin.tests.widgetset.client; import java.util.Date; import java.util.logging.Logger; -import com.google.gwt.json.client.JSONObject; -import com.google.gwt.json.client.JSONValue; import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ValueMap; import com.vaadin.shared.ApplicationConstants; import com.vaadin.tests.widgetset.server.csrf.ui.CsrfTokenDisabled; +import elemental.json.JsonObject; +import elemental.json.JsonValue; + /** * Mock ApplicationConnection for several issues where we need to hack it. * @@ -71,9 +72,9 @@ public class MockApplicationConnection extends ApplicationConnection { } @Override - protected void doUidlRequest(String uri, JSONObject payload) { - JSONValue jsonValue = payload.get(ApplicationConstants.CSRF_TOKEN); - lastCsrfTokenSent = jsonValue != null ? jsonValue.toString() : null; + protected void doUidlRequest(String uri, JsonObject payload) { + JsonValue jsonValue = payload.get(ApplicationConstants.CSRF_TOKEN); + lastCsrfTokenSent = jsonValue != null ? jsonValue.toJson() : null; super.doUidlRequest(uri, payload); } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java new file mode 100644 index 0000000000..7c2693db1d --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/NoLayoutRpc.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client; + +import com.vaadin.shared.annotations.NoLayout; +import com.vaadin.shared.communication.ClientRpc; + +public interface NoLayoutRpc extends ClientRpc { + + @NoLayout + public void doRpc(); + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java index 60a3fb1448..e71f9f1230 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/RoundTripTesterRpc.java @@ -15,10 +15,12 @@ */ package com.vaadin.tests.widgetset.client; +import com.vaadin.shared.annotations.NoLayout; import com.vaadin.shared.communication.ClientRpc; import com.vaadin.shared.communication.ServerRpc; public interface RoundTripTesterRpc extends ServerRpc, ClientRpc { + @NoLayout public void ping(int nr, String payload); public void done(); diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java index 7758cdc2ac..07acd3d021 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java @@ -35,6 +35,13 @@ import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.tests.widgetset.server.SerializerTestExtension; +import elemental.json.Json; +import elemental.json.JsonBoolean; +import elemental.json.JsonObject; +import elemental.json.JsonString; +import elemental.json.JsonType; +import elemental.json.JsonValue; + @Connect(SerializerTestExtension.class) public class SerializerTestConnector extends AbstractExtensionConnector { @@ -259,6 +266,27 @@ public class SerializerTestConnector extends AbstractExtensionConnector { } @Override + public void sendJson(JsonValue value1, JsonValue value2, + JsonString string) { + if (value1.getType() != JsonType.BOOLEAN) { + throw new RuntimeException("Expected boolean, got " + + value1.toJson()); + } + + if (value2.getType() != JsonType.NULL) { + throw new RuntimeException("Expected null, got " + + value2.toJson()); + } + + JsonObject returnObject = Json.createObject(); + returnObject.put("b", !((JsonBoolean) value1).asBoolean()); + returnObject.put("s", string); + + rpc.sendJson(returnObject, Json.createNull(), + Json.create("value")); + } + + @Override public void log(String message) { // Do nothing, used only in the other direction } @@ -311,6 +339,11 @@ public class SerializerTestConnector extends AbstractExtensionConnector { rpc.log("state.doubleObjectValue: " + getState().doubleObjectValue); rpc.log("state.doubleArray: " + Arrays.toString(getState().doubleArray)); + rpc.log("state.jsonNull: " + getState().jsonNull.getType().name()); + rpc.log("state.jsonString: " + + ((JsonString) getState().jsonString).getString()); + rpc.log("state.jsonBoolean: " + getState().jsonBoolean.getBoolean()); + /* * TODO public double doubleValue; public Double DoubleValue; public * double[] doubleArray; ; diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java index 6b4c4e7ac1..4baebc819e 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java @@ -26,6 +26,9 @@ import com.vaadin.shared.communication.ClientRpc; import com.vaadin.shared.communication.ServerRpc; import com.vaadin.shared.ui.label.ContentMode; +import elemental.json.JsonString; +import elemental.json.JsonValue; + @SuppressWarnings("javadoc") public interface SerializerTestRpc extends ServerRpc, ClientRpc { public void sendBoolean(boolean value, Boolean boxedValue, boolean[] array); @@ -82,5 +85,7 @@ public interface SerializerTestRpc extends ServerRpc, ClientRpc { public void sendDate(Date date); + public void sendJson(JsonValue value1, JsonValue value2, JsonString string); + public void log(String string); } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java index faf41fbf88..31ff58971f 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java @@ -24,6 +24,9 @@ import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.Connector; import com.vaadin.shared.ui.label.ContentMode; +import elemental.json.JsonBoolean; +import elemental.json.JsonValue; + public class SerializerTestState extends AbstractComponentState { public boolean booleanValue; @@ -99,4 +102,8 @@ public class SerializerTestState extends AbstractComponentState { public BeanWithAbstractSuperclass beanWithAbstractSuperclass; + public JsonValue jsonNull = null; + public JsonValue jsonString = null; + public JsonBoolean jsonBoolean = null; + } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/TestWidgetConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/TestWidgetConnector.java new file mode 100644 index 0000000000..33a8956810 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/TestWidgetConnector.java @@ -0,0 +1,100 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client; + +import java.util.HashMap; +import java.util.Map; + +import com.google.gwt.core.client.GWT; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.SimplePanel; +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.annotations.OnStateChange; +import com.vaadin.client.metadata.Invoker; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.client.ui.SubPartAware; +import com.vaadin.shared.AbstractComponentState; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.TestWidgetComponent; + +@Connect(TestWidgetComponent.class) +public class TestWidgetConnector extends AbstractComponentConnector { + public static class SubPartAwareSimplePanel extends SimplePanel implements + SubPartAware { + @Override + public Element getSubPartElement(String subPart) { + Widget target = getWidget(); + if (target instanceof SubPartAware) { + return ((SubPartAware) target).getSubPartElement(subPart); + } else { + return null; + } + } + + @Override + public String getSubPartName(Element subElement) { + Widget target = getWidget(); + if (target instanceof SubPartAware) { + return ((SubPartAware) target).getSubPartName(subElement); + + } else { + return null; + } + } + + } + + public static class TestWidgetState extends AbstractComponentState { + public String widgetClass; + } + + private final TestWidgetRegistry registry = GWT + .create(TestWidgetRegistry.class); + + public static abstract class TestWidgetRegistry { + private Map<String, Invoker> creators = new HashMap<String, Invoker>(); + + // Called by generated sub class + protected void register(String widgetClass, Invoker creator) { + creators.put(widgetClass, creator); + } + + public Widget createWidget(String widgetClass) { + Invoker invoker = creators.get(widgetClass); + if (invoker == null) { + return new Label("Widget not found: " + widgetClass); + } else { + return (Widget) invoker.invoke(null); + } + } + } + + @OnStateChange("widgetClass") + private void updateWidgetClass() { + getWidget().setWidget(registry.createWidget(getState().widgetClass)); + } + + @Override + public TestWidgetState getState() { + return (TestWidgetState) super.getState(); + } + + @Override + public SubPartAwareSimplePanel getWidget() { + return (SubPartAwareSimplePanel) super.getWidget(); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java new file mode 100644 index 0000000000..761f32bc9a --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorBasicClientFeaturesWidget.java @@ -0,0 +1,702 @@ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.Duration; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.TableCellElement; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.vaadin.client.widget.escalator.EscalatorUpdater; +import com.vaadin.client.widget.escalator.FlyweightCell; +import com.vaadin.client.widget.escalator.Row; +import com.vaadin.client.widget.escalator.RowContainer; +import com.vaadin.client.widgets.Escalator; + +public class EscalatorBasicClientFeaturesWidget extends + PureGWTTestApplication<Escalator> { + + public static class LogWidget extends Composite { + + private static final int MAX_LOG = 9; + + private final HTML html = new HTML(); + private final List<String> logs = new ArrayList<String>(); + private Escalator escalator; + + public LogWidget() { + initWidget(html); + getElement().setId("log"); + } + + public void setEscalator(Escalator escalator) { + this.escalator = escalator; + } + + public void updateDebugLabel() { + int headers = escalator.getHeader().getRowCount(); + int bodys = escalator.getBody().getRowCount(); + int footers = escalator.getFooter().getRowCount(); + int columns = escalator.getColumnConfiguration().getColumnCount(); + + while (logs.size() > MAX_LOG) { + logs.remove(0); + } + + String logString = "<hr>"; + for (String log : logs) { + logString += log + "<br>"; + } + + html.setHTML("Columns: " + columns + "<br>" + // + "Header rows: " + headers + "<br>" + // + "Body rows: " + bodys + "<br>" + // + "Footer rows: " + footers + "<br>" + // + logString); + } + + public void log(String string) { + logs.add((Duration.currentTimeMillis() % 10000) + ": " + string); + } + } + + public static class UpdaterLifetimeWidget extends + EscalatorBasicClientFeaturesWidget { + + private final EscalatorUpdater debugUpdater = new EscalatorUpdater() { + @Override + public void preAttach(Row row, Iterable<FlyweightCell> cellsToAttach) { + log("preAttach", cellsToAttach); + } + + @Override + public void postAttach(Row row, + Iterable<FlyweightCell> attachedCells) { + log("postAttach", attachedCells); + } + + @Override + public void update(Row row, Iterable<FlyweightCell> cellsToUpdate) { + log("update", cellsToUpdate); + } + + @Override + public void preDetach(Row row, Iterable<FlyweightCell> cellsToDetach) { + log("preDetach", cellsToDetach); + } + + @Override + public void postDetach(Row row, + Iterable<FlyweightCell> detachedCells) { + log("postDetach", detachedCells); + } + + private void log(String methodName, Iterable<FlyweightCell> cells) { + if (!cells.iterator().hasNext()) { + return; + } + + TableCellElement cellElement = cells.iterator().next() + .getElement(); + boolean isAttached = cellElement.getParentElement() != null + && cellElement.getParentElement().getParentElement() != null; + logWidget.log(methodName + ": elementIsAttached == " + + isAttached); + } + }; + + public UpdaterLifetimeWidget() { + super(); + escalator.getHeader().setEscalatorUpdater(debugUpdater); + escalator.getBody().setEscalatorUpdater(debugUpdater); + escalator.getFooter().setEscalatorUpdater(debugUpdater); + } + } + + private static final String COLUMNS_AND_ROWS_MENU = "Columns and Rows"; + private static final String GENERAL_MENU = "General"; + private static final String FEATURES_MENU = "Features"; + + private static abstract class TestEscalatorUpdater implements + EscalatorUpdater { + + @Override + public void preAttach(Row row, Iterable<FlyweightCell> cellsToAttach) { + // noop + } + + @Override + public void postAttach(Row row, Iterable<FlyweightCell> attachedCells) { + // noop + } + + @Override + public void preDetach(Row row, Iterable<FlyweightCell> cellsToDetach) { + // noop + } + + @Override + public void postDetach(Row row, Iterable<FlyweightCell> detachedCells) { + // noop + } + } + + private class Data { + private int columnCounter = 0; + private int rowCounter = 0; + private final List<Integer> columns = new ArrayList<Integer>(); + private final List<Integer> rows = new ArrayList<Integer>(); + + @SuppressWarnings("boxing") + public void insertRows(final int offset, final int amount) { + final List<Integer> newRows = new ArrayList<Integer>(); + for (int i = 0; i < amount; i++) { + newRows.add(rowCounter++); + } + rows.addAll(offset, newRows); + } + + @SuppressWarnings("boxing") + public void insertColumns(final int offset, final int amount) { + final List<Integer> newColumns = new ArrayList<Integer>(); + for (int i = 0; i < amount; i++) { + newColumns.add(columnCounter++); + } + columns.addAll(offset, newColumns); + } + + public EscalatorUpdater createHeaderUpdater() { + return new TestEscalatorUpdater() { + @Override + public void update(final Row row, + final Iterable<FlyweightCell> cellsToUpdate) { + for (final FlyweightCell cell : cellsToUpdate) { + final Integer columnName = columns + .get(cell.getColumn()); + cell.getElement().setInnerText("Header " + columnName); + + if (colspan == Colspan.NORMAL) { + if (cell.getColumn() % 2 == 0) { + cell.setColSpan(2); + } + } else if (colspan == Colspan.CRAZY) { + if (cell.getColumn() % 3 == 0) { + cell.setColSpan(2); + } + } + } + } + }; + } + + public EscalatorUpdater createFooterUpdater() { + return new TestEscalatorUpdater() { + @Override + public void update(final Row row, + final Iterable<FlyweightCell> cellsToUpdate) { + for (final FlyweightCell cell : cellsToUpdate) { + final Integer columnName = columns + .get(cell.getColumn()); + cell.getElement().setInnerText("Footer " + columnName); + + if (colspan == Colspan.NORMAL) { + if (cell.getColumn() % 2 == 0) { + cell.setColSpan(2); + } + } else if (colspan == Colspan.CRAZY) { + if (cell.getColumn() % 3 == 1) { + cell.setColSpan(2); + } + } + } + } + }; + } + + public EscalatorUpdater createBodyUpdater() { + return new TestEscalatorUpdater() { + + public void renderCell(final FlyweightCell cell) { + final Integer columnName = columns.get(cell.getColumn()); + final Integer rowName = rows.get(cell.getRow()); + String cellInfo = columnName + "," + rowName; + + if (cell.getColumn() > 0) { + cell.getElement().setInnerText("Cell: " + cellInfo); + } else { + cell.getElement().setInnerText( + "Row " + cell.getRow() + ": " + cellInfo); + } + + if (colspan == Colspan.NORMAL) { + if (cell.getColumn() % 2 == 0) { + cell.setColSpan(2); + } + } else if (colspan == Colspan.CRAZY) { + if (cell.getColumn() % 3 == cell.getRow() % 3) { + cell.setColSpan(2); + } + } + } + + @Override + public void update(final Row row, + final Iterable<FlyweightCell> cellsToUpdate) { + for (final FlyweightCell cell : cellsToUpdate) { + renderCell(cell); + } + } + }; + } + + public void removeRows(final int offset, final int amount) { + for (int i = 0; i < amount; i++) { + rows.remove(offset); + } + } + + public void removeColumns(final int offset, final int amount) { + for (int i = 0; i < amount; i++) { + columns.remove(offset); + } + } + } + + protected final Escalator escalator; + private final Data data = new Data(); + + private enum Colspan { + NONE, NORMAL, CRAZY; + } + + private Colspan colspan = Colspan.NONE; + protected final LogWidget logWidget = new LogWidget(); + + public EscalatorBasicClientFeaturesWidget() { + super(new EscalatorProxy()); + escalator = getTestedWidget(); + logWidget.setEscalator(escalator); + + ((EscalatorProxy) escalator).setLogWidget(logWidget); + addNorth(logWidget, 200); + + final RowContainer header = escalator.getHeader(); + header.setEscalatorUpdater(data.createHeaderUpdater()); + + final RowContainer footer = escalator.getFooter(); + footer.setEscalatorUpdater(data.createFooterUpdater()); + + escalator.getBody().setEscalatorUpdater(data.createBodyUpdater()); + + setWidth("500px"); + setHeight("500px"); + + escalator.getElement().getStyle().setZIndex(0); + addNorth(escalator, 500); + + createGeneralMenu(); + createColumnMenu(); + createHeaderRowsMenu(); + createBodyRowsMenu(); + createFooterRowsMenu(); + createColumnsAndRowsMenu(); + createFrozenMenu(); + createColspanMenu(); + } + + private void createFrozenMenu() { + String[] menupath = { FEATURES_MENU, "Frozen columns" }; + addMenuCommand("Freeze 1 column", new ScheduledCommand() { + @Override + public void execute() { + escalator.getColumnConfiguration().setFrozenColumnCount(1); + } + }, menupath); + addMenuCommand("Freeze 0 columns", new ScheduledCommand() { + @Override + public void execute() { + escalator.getColumnConfiguration().setFrozenColumnCount(0); + } + }, menupath); + } + + private void createColspanMenu() { + String[] menupath = { FEATURES_MENU, "Column spanning" }; + addMenuCommand("Apply normal colspan", new ScheduledCommand() { + @Override + public void execute() { + colspan = Colspan.NORMAL; + refreshEscalator(); + } + }, menupath); + addMenuCommand("Apply crazy colspan", new ScheduledCommand() { + @Override + public void execute() { + colspan = Colspan.CRAZY; + refreshEscalator(); + } + }, menupath); + addMenuCommand("Apply no colspan", new ScheduledCommand() { + @Override + public void execute() { + colspan = Colspan.NONE; + refreshEscalator(); + } + }, menupath); + } + + private void createColumnsAndRowsMenu() { + String[] menupath = { COLUMNS_AND_ROWS_MENU }; + addMenuCommand("Add one of each row", new ScheduledCommand() { + @Override + public void execute() { + insertRows(escalator.getHeader(), 0, 1); + insertRows(escalator.getBody(), 0, 1); + insertRows(escalator.getFooter(), 0, 1); + } + }, menupath); + addMenuCommand("Remove one of each row", new ScheduledCommand() { + @Override + public void execute() { + removeRows(escalator.getHeader(), 0, 1); + removeRows(escalator.getBody(), 0, 1); + removeRows(escalator.getFooter(), 0, 1); + } + }, menupath); + } + + private void createGeneralMenu() { + String[] menupath = { GENERAL_MENU }; + + addMenuCommand("Detach Escalator", new ScheduledCommand() { + @Override + public void execute() { + escalator.removeFromParent(); + } + }, menupath); + + addMenuCommand("Attach Escalator", new ScheduledCommand() { + @Override + public void execute() { + if (!escalator.isAttached()) { + addNorth(escalator, 500); + } + } + }, menupath); + + addMenuCommand("Clear (columns, then rows)", new ScheduledCommand() { + @Override + public void execute() { + resetColRow(); + } + }, menupath); + addMenuCommand("Clear (rows, then columns)", new ScheduledCommand() { + @Override + public void execute() { + resetRowCol(); + } + }, menupath); + addMenuCommand("Populate Escalator (columns, then rows)", + new ScheduledCommand() { + @Override + public void execute() { + resetColRow(); + insertColumns(0, 10); + insertRows(escalator.getHeader(), 0, 1); + insertRows(escalator.getBody(), 0, 100); + insertRows(escalator.getFooter(), 0, 1); + } + }, menupath); + addMenuCommand("Populate Escalator (rows, then columns)", + new ScheduledCommand() { + @Override + public void execute() { + resetColRow(); + insertRows(escalator.getHeader(), 0, 1); + insertRows(escalator.getBody(), 0, 100); + insertRows(escalator.getFooter(), 0, 1); + insertColumns(0, 10); + } + }, menupath); + + createSizeMenu(); + } + + private void createSizeMenu() { + String[] menupath = new String[] { "General", "Size" }; + + addSizeMenuItem(null, "height", menupath); + addSizeMenuItem("200px", "height", menupath); + addSizeMenuItem("400px", "height", menupath); + addSizeMenuItem(null, "width", menupath); + addSizeMenuItem("200px", "width", menupath); + addSizeMenuItem("400px", "width", menupath); + } + + private void addSizeMenuItem(final String size, final String direction, + String[] menupath) { + final String title = (size != null ? size : "undefined"); + addMenuCommand(title + " " + direction, new ScheduledCommand() { + @Override + public void execute() { + if (direction.equals("height")) { + escalator.setHeight(size); + } else { + escalator.setWidth(size); + } + } + }, menupath); + } + + private void createColumnMenu() { + String[] menupath = { COLUMNS_AND_ROWS_MENU, "Columns" }; + addMenuCommand("Add one column to beginning", new ScheduledCommand() { + @Override + public void execute() { + insertColumns(0, 1); + } + }, menupath); + addMenuCommand("Add one column to end", new ScheduledCommand() { + @Override + public void execute() { + insertColumns(escalator.getColumnConfiguration() + .getColumnCount(), 1); + } + }, menupath); + addMenuCommand("Add ten columns", new ScheduledCommand() { + @Override + public void execute() { + insertColumns(0, 10); + } + }, menupath); + addMenuCommand("Remove one column from beginning", + new ScheduledCommand() { + @Override + public void execute() { + removeColumns(0, 1); + } + }, menupath); + addMenuCommand("Remove one column from end", new ScheduledCommand() { + @Override + public void execute() { + removeColumns(escalator.getColumnConfiguration() + .getColumnCount() - 1, 1); + } + }, menupath); + + addMenuCommand("Refresh first column", new ScheduledCommand() { + @Override + public void execute() { + escalator.getColumnConfiguration().refreshColumns(0, 1); + } + }, menupath); + + addMenuCommand("Resize first column to max width", + new ScheduledCommand() { + @Override + public void execute() { + escalator.getColumnConfiguration() + .setColumnWidth(0, -1); + } + }, menupath); + + addMenuCommand("Resize first column to 100 px", new ScheduledCommand() { + @Override + public void execute() { + escalator.getColumnConfiguration().setColumnWidth(0, 100); + } + }, menupath); + } + + private void createHeaderRowsMenu() { + String[] menupath = { COLUMNS_AND_ROWS_MENU, "Header Rows" }; + createRowsMenu(escalator.getHeader(), menupath); + } + + private void createFooterRowsMenu() { + String[] menupath = { COLUMNS_AND_ROWS_MENU, "Footer Rows" }; + createRowsMenu(escalator.getFooter(), menupath); + } + + private void createBodyRowsMenu() { + String[] menupath = { COLUMNS_AND_ROWS_MENU, "Body Rows" }; + createRowsMenu(escalator.getBody(), menupath); + + addMenuCommand("Add 5 rows to top", new ScheduledCommand() { + @Override + public void execute() { + insertRows(escalator.getBody(), 0, 5); + } + }, menupath); + addMenuCommand("Add 50 rows to top", new ScheduledCommand() { + @Override + public void execute() { + insertRows(escalator.getBody(), 0, 50); + } + }, menupath); + addMenuCommand("Remove 5 rows from bottom", new ScheduledCommand() { + @Override + public void execute() { + removeRows(escalator.getBody(), escalator.getBody() + .getRowCount() - 5, 5); + } + }, menupath); + addMenuCommand("Remove 50 rows from bottom", new ScheduledCommand() { + @Override + public void execute() { + removeRows(escalator.getBody(), escalator.getBody() + .getRowCount() - 50, 50); + } + }, menupath); + addMenuCommand("Remove 50 rows from almost bottom", + new ScheduledCommand() { + @Override + public void execute() { + removeRows(escalator.getBody(), escalator.getBody() + .getRowCount() - 60, 50); + } + }, menupath); + addMenuCommand("Remove all, insert 30 and scroll 40px", + new ScheduledCommand() { + @Override + public void execute() { + removeRows(escalator.getBody(), 0, escalator.getBody() + .getRowCount()); + insertRows(escalator.getBody(), 0, 30); + escalator.setScrollTop(40); + } + }, menupath); + } + + private void createRowsMenu(final RowContainer container, String[] menupath) { + addMenuCommand("Add one row to beginning", new ScheduledCommand() { + @Override + public void execute() { + int offset = 0; + int number = 1; + insertRows(container, offset, number); + } + }, menupath); + addMenuCommand("Add one row to end", new ScheduledCommand() { + @Override + public void execute() { + int offset = container.getRowCount(); + int number = 1; + insertRows(container, offset, number); + } + }, menupath); + addMenuCommand("Remove one row from beginning", new ScheduledCommand() { + @Override + public void execute() { + int offset = 0; + int number = 1; + removeRows(container, offset, number); + } + }, menupath); + addMenuCommand("Remove one row from end", new ScheduledCommand() { + @Override + public void execute() { + int offset = container.getRowCount() - 1; + int number = 1; + removeRows(container, offset, number); + } + }, menupath); + addMenuCommand("Remove all rows", new ScheduledCommand() { + @Override + public void execute() { + if (container.getRowCount() > 0) { + removeRows(container, 0, container.getRowCount()); + } + } + }, menupath); + } + + private void insertRows(final RowContainer container, int offset, int number) { + if (container == escalator.getBody()) { + data.insertRows(offset, number); + escalator.getBody().insertRows(offset, number); + } else { + container.insertRows(offset, number); + } + } + + private void removeRows(final RowContainer container, int offset, int number) { + if (container == escalator.getBody()) { + data.removeRows(offset, number); + escalator.getBody().removeRows(offset, number); + } else { + container.removeRows(offset, number); + } + } + + private void insertColumns(final int offset, final int number) { + data.insertColumns(offset, number); + escalator.getColumnConfiguration().insertColumns(offset, number); + } + + private void removeColumns(final int offset, final int number) { + data.removeColumns(offset, number); + escalator.getColumnConfiguration().removeColumns(offset, number); + } + + private void resetColRow() { + if (escalator.getColumnConfiguration().getColumnCount() > 0) { + removeColumns(0, escalator.getColumnConfiguration() + .getColumnCount()); + } + if (escalator.getFooter().getRowCount() > 0) { + removeRows(escalator.getFooter(), 0, escalator.getFooter() + .getRowCount()); + } + + if (escalator.getBody().getRowCount() > 0) { + removeRows(escalator.getBody(), 0, escalator.getBody() + .getRowCount()); + } + + if (escalator.getHeader().getRowCount() > 0) { + removeRows(escalator.getHeader(), 0, escalator.getHeader() + .getRowCount()); + } + } + + private void resetRowCol() { + if (escalator.getFooter().getRowCount() > 0) { + removeRows(escalator.getFooter(), 0, escalator.getFooter() + .getRowCount()); + } + + if (escalator.getBody().getRowCount() > 0) { + removeRows(escalator.getBody(), 0, escalator.getBody() + .getRowCount()); + } + + if (escalator.getHeader().getRowCount() > 0) { + removeRows(escalator.getHeader(), 0, escalator.getHeader() + .getRowCount()); + } + + if (escalator.getColumnConfiguration().getColumnCount() > 0) { + removeColumns(0, escalator.getColumnConfiguration() + .getColumnCount()); + } + } + + private void refreshEscalator() { + if (escalator.getHeader().getRowCount() > 0) { + escalator.getHeader().refreshRows(0, + escalator.getHeader().getRowCount()); + } + + if (escalator.getBody().getRowCount() > 0) { + escalator.getBody().refreshRows(0, + escalator.getBody().getRowCount()); + } + + if (escalator.getFooter().getRowCount() > 0) { + escalator.getFooter().refreshRows(0, + escalator.getFooter().getRowCount()); + } + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java new file mode 100644 index 0000000000..53bf96c587 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/EscalatorProxy.java @@ -0,0 +1,218 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import com.google.gwt.dom.client.Element; +import com.google.gwt.dom.client.TableRowElement; +import com.vaadin.client.widget.escalator.Cell; +import com.vaadin.client.widget.escalator.ColumnConfiguration; +import com.vaadin.client.widget.escalator.EscalatorUpdater; +import com.vaadin.client.widget.escalator.RowContainer; +import com.vaadin.client.widgets.Escalator; +import com.vaadin.tests.widgetset.client.grid.EscalatorBasicClientFeaturesWidget.LogWidget; + +public class EscalatorProxy extends Escalator { + private class ColumnConfigurationProxy implements ColumnConfiguration { + private ColumnConfiguration columnConfiguration; + + public ColumnConfigurationProxy(ColumnConfiguration columnConfiguration) { + this.columnConfiguration = columnConfiguration; + } + + @Override + public void removeColumns(int index, int numberOfColumns) + throws IndexOutOfBoundsException, IllegalArgumentException { + columnConfiguration.removeColumns(index, numberOfColumns); + logWidget.log("removeColumns " + index + ", " + numberOfColumns); + logWidget.updateDebugLabel(); + } + + @Override + public void insertColumns(int index, int numberOfColumns) + throws IndexOutOfBoundsException, IllegalArgumentException { + columnConfiguration.insertColumns(index, numberOfColumns); + logWidget.log("insertColumns " + index + ", " + numberOfColumns); + logWidget.updateDebugLabel(); + } + + @Override + public int getColumnCount() { + return columnConfiguration.getColumnCount(); + } + + @Override + public void setFrozenColumnCount(int count) + throws IllegalArgumentException { + columnConfiguration.setFrozenColumnCount(count); + } + + @Override + public int getFrozenColumnCount() { + return columnConfiguration.getFrozenColumnCount(); + } + + @Override + public void setColumnWidth(int index, double px) + throws IllegalArgumentException { + columnConfiguration.setColumnWidth(index, px); + } + + @Override + public double getColumnWidth(int index) throws IllegalArgumentException { + return columnConfiguration.getColumnWidth(index); + } + + @Override + public double getColumnWidthActual(int index) + throws IllegalArgumentException { + return columnConfiguration.getColumnWidthActual(index); + } + + @Override + public void refreshColumns(int index, int numberOfColumns) + throws IndexOutOfBoundsException, IllegalArgumentException { + columnConfiguration.refreshColumns(index, numberOfColumns); + } + } + + private class RowContainerProxy implements RowContainer { + private final RowContainer rowContainer; + + public RowContainerProxy(RowContainer rowContainer) { + this.rowContainer = rowContainer; + } + + @Override + public EscalatorUpdater getEscalatorUpdater() { + return rowContainer.getEscalatorUpdater(); + } + + @Override + public void setEscalatorUpdater(EscalatorUpdater escalatorUpdater) + throws IllegalArgumentException { + rowContainer.setEscalatorUpdater(escalatorUpdater); + } + + @Override + public void removeRows(int index, int numberOfRows) + throws IndexOutOfBoundsException, IllegalArgumentException { + rowContainer.removeRows(index, numberOfRows); + logWidget.log(rowContainer.getClass().getSimpleName() + + " removeRows " + index + ", " + numberOfRows); + logWidget.updateDebugLabel(); + } + + @Override + public void insertRows(int index, int numberOfRows) + throws IndexOutOfBoundsException, IllegalArgumentException { + rowContainer.insertRows(index, numberOfRows); + logWidget.log(rowContainer.getClass().getSimpleName() + + " insertRows " + index + ", " + numberOfRows); + logWidget.updateDebugLabel(); + } + + @Override + public void refreshRows(int index, int numberOfRows) + throws IndexOutOfBoundsException, IllegalArgumentException { + rowContainer.refreshRows(index, numberOfRows); + logWidget.log(rowContainer.getClass().getSimpleName() + + " refreshRows " + index + ", " + numberOfRows); + } + + @Override + public int getRowCount() { + return rowContainer.getRowCount(); + } + + @Override + public void setDefaultRowHeight(double px) throws IllegalArgumentException { + rowContainer.setDefaultRowHeight(px); + } + + @Override + public double getDefaultRowHeight() { + return rowContainer.getDefaultRowHeight(); + } + + @Override + public Cell getCell(Element element) { + return rowContainer.getCell(element); + } + + @Override + public TableRowElement getRowElement(int index) + throws IndexOutOfBoundsException, IllegalStateException { + return rowContainer.getRowElement(index); + } + + @Override + public Element getElement() { + return rowContainer.getElement(); + } + + } + + private RowContainer headerProxy = null; + private RowContainer bodyProxy = null; + private RowContainer footerProxy = null; + private ColumnConfiguration columnProxy = null; + private LogWidget logWidget; + + @Override + public RowContainer getHeader() { + if (headerProxy == null) { + headerProxy = new RowContainerProxy(super.getHeader()); + } + return headerProxy; + } + + @Override + public RowContainer getFooter() { + if (footerProxy == null) { + footerProxy = new RowContainerProxy(super.getFooter()); + } + return footerProxy; + } + + @Override + public RowContainer getBody() { + if (bodyProxy == null) { + bodyProxy = new RowContainerProxy(super.getBody()); + } + return bodyProxy; + } + + @Override + public ColumnConfiguration getColumnConfiguration() { + if (columnProxy == null) { + columnProxy = new ColumnConfigurationProxy( + super.getColumnConfiguration()); + } + return columnProxy; + } + + public void setLogWidget(LogWidget logWidget) { + this.logWidget = logWidget; + logWidget.updateDebugLabel(); + } + + @Override + public void setScrollTop(double scrollTop) { + logWidget.log("setScrollTop " + scrollTop); + logWidget.updateDebugLabel(); + super.setScrollTop(scrollTop); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java new file mode 100644 index 0000000000..25a04b88f9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java @@ -0,0 +1,1173 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.logging.Logger; + +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.event.shared.HandlerRegistration; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.HTML; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.TextBox; +import com.vaadin.client.data.DataSource; +import com.vaadin.client.data.DataSource.RowHandle; +import com.vaadin.client.renderers.DateRenderer; +import com.vaadin.client.renderers.HtmlRenderer; +import com.vaadin.client.renderers.NumberRenderer; +import com.vaadin.client.renderers.Renderer; +import com.vaadin.client.renderers.TextRenderer; +import com.vaadin.client.ui.VLabel; +import com.vaadin.client.widget.grid.CellReference; +import com.vaadin.client.widget.grid.CellStyleGenerator; +import com.vaadin.client.widget.grid.EditorHandler; +import com.vaadin.client.widget.grid.RendererCellReference; +import com.vaadin.client.widget.grid.RowReference; +import com.vaadin.client.widget.grid.RowStyleGenerator; +import com.vaadin.client.widget.grid.datasources.ListDataSource; +import com.vaadin.client.widget.grid.datasources.ListSorter; +import com.vaadin.client.widget.grid.events.BodyKeyDownHandler; +import com.vaadin.client.widget.grid.events.BodyKeyPressHandler; +import com.vaadin.client.widget.grid.events.BodyKeyUpHandler; +import com.vaadin.client.widget.grid.events.FooterKeyDownHandler; +import com.vaadin.client.widget.grid.events.FooterKeyPressHandler; +import com.vaadin.client.widget.grid.events.FooterKeyUpHandler; +import com.vaadin.client.widget.grid.events.GridKeyDownEvent; +import com.vaadin.client.widget.grid.events.GridKeyPressEvent; +import com.vaadin.client.widget.grid.events.GridKeyUpEvent; +import com.vaadin.client.widget.grid.events.HeaderKeyDownHandler; +import com.vaadin.client.widget.grid.events.HeaderKeyPressHandler; +import com.vaadin.client.widget.grid.events.HeaderKeyUpHandler; +import com.vaadin.client.widget.grid.events.ScrollEvent; +import com.vaadin.client.widget.grid.events.ScrollHandler; +import com.vaadin.client.widget.grid.selection.SelectionModel.None; +import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.FooterRow; +import com.vaadin.client.widgets.Grid.HeaderRow; +import com.vaadin.client.widgets.Grid.SelectionMode; +import com.vaadin.tests.widgetset.client.grid.GridBasicClientFeaturesWidget.Data; + +/** + * Grid basic client features test application. + * + * @since + * @author Vaadin Ltd + */ +public class GridBasicClientFeaturesWidget extends + PureGWTTestApplication<Grid<List<Data>>> { + public static final String ROW_STYLE_GENERATOR_NONE = "None"; + public static final String ROW_STYLE_GENERATOR_ROW_INDEX = "Row numbers"; + public static final String ROW_STYLE_GENERATOR_EVERY_THIRD = "Every third"; + + public static final String CELL_STYLE_GENERATOR_NONE = "None"; + public static final String CELL_STYLE_GENERATOR_SIMPLE = "Simple"; + public static final String CELL_STYLE_GENERATOR_COL_INDEX = "Column index"; + + public static enum Renderers { + TEXT_RENDERER, HTML_RENDERER, NUMBER_RENDERER, DATE_RENDERER; + } + + private class TestEditorHandler implements EditorHandler<List<Data>> { + + private Map<Grid.Column<?, ?>, TextBox> widgets = new HashMap<Grid.Column<?, ?>, TextBox>(); + + private Label log = new Label(); + + { + log.addStyleName("grid-editor-log"); + addSouth(log, 20); + } + + @Override + public void bind(EditorRequest<List<Data>> request) { + List<Data> rowData = ds.getRow(request.getRowIndex()); + + boolean hasSelectionColumn = !(grid.getSelectionModel() instanceof None); + for (int i = 0; i < rowData.size(); i++) { + int columnIndex = hasSelectionColumn ? i + 1 : i; + getWidget(columnIndex).setText(rowData.get(i).value.toString()); + } + request.success(); + } + + @Override + public void cancel(EditorRequest<List<Data>> request) { + log.setText("Row " + request.getRowIndex() + " edit cancelled"); + } + + @Override + public void save(EditorRequest<List<Data>> request) { + try { + log.setText("Row " + request.getRowIndex() + " edit committed"); + List<Data> rowData = ds.getRow(request.getRowIndex()); + + int i = 0; + for (; i < COLUMNS - MANUALLY_FORMATTED_COLUMNS; i++) { + rowData.get(i).value = getWidget(i).getText(); + } + + rowData.get(i).value = Integer + .valueOf(getWidget(i++).getText()); + rowData.get(i).value = new Date(getWidget(i++).getText()); + rowData.get(i).value = getWidget(i++).getText(); + rowData.get(i).value = Integer + .valueOf(getWidget(i++).getText()); + rowData.get(i).value = Integer + .valueOf(getWidget(i++).getText()); + + // notify data source of changes + ds.asList().set(request.getRowIndex(), rowData); + request.success(); + } catch (Exception e) { + Logger.getLogger(getClass().getName()).warning(e.toString()); + request.fail(); + } + } + + @Override + public TextBox getWidget(Grid.Column<?, List<Data>> column) { + if (grid.getColumns().indexOf(column) == 0 + && !(grid.getSelectionModel() instanceof None)) { + return null; + } + + TextBox w = widgets.get(column); + if (w == null) { + w = new TextBox(); + w.getElement().getStyle().setMargin(0, Unit.PX); + widgets.put(column, w); + } + return w; + } + + private TextBox getWidget(int i) { + return getWidget(grid.getColumn(i)); + } + } + + private static final int MANUALLY_FORMATTED_COLUMNS = 5; + public static final int COLUMNS = 12; + public static final int ROWS = 1000; + + private final Grid<List<Data>> grid; + private List<List<Data>> data; + private final ListDataSource<List<Data>> ds; + private final ListSorter<List<Data>> sorter; + + /** + * Our basic data object + */ + public final static class Data { + Object value; + } + + /** + * @since + * @return + */ + private List<List<Data>> createData(int rowCount) { + List<List<Data>> dataList = new ArrayList<List<Data>>(); + Random rand = new Random(); + rand.setSeed(13334); + long timestamp = 0; + for (int row = 0; row < rowCount; row++) { + + List<Data> datarow = createDataRow(COLUMNS); + dataList.add(datarow); + Data d; + + int col = 0; + for (; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; ++col) { + d = datarow.get(col); + d.value = "(" + row + ", " + col + ")"; + } + + d = datarow.get(col++); + d.value = Integer.valueOf(row); + + d = datarow.get(col++); + d.value = new Date(timestamp); + timestamp += 91250000; // a bit over a day, just to get + // variation + + d = datarow.get(col++); + d.value = "<b>" + row + "</b>"; + + d = datarow.get(col++); + d.value = Integer.valueOf(rand.nextInt()); + + d = datarow.get(col++); + d.value = Integer.valueOf(rand.nextInt(5)); + } + + return dataList; + } + + /** + * Convenience method for creating a list of Data objects to be used as a + * Row in the data source + * + * @param cols + * number of columns (items) to include in the row + * @return + */ + private List<Data> createDataRow(int cols) { + List<Data> list = new ArrayList<Data>(cols); + for (int i = 0; i < cols; ++i) { + list.add(new Data()); + } + return list; + } + + @SuppressWarnings("unchecked") + public GridBasicClientFeaturesWidget() { + super(new Grid<List<Data>>()); + + // Initialize data source + data = createData(ROWS); + + ds = new ListDataSource<List<Data>>(data); + grid = getTestedWidget(); + grid.getElement().setId("testComponent"); + grid.setDataSource(ds); + grid.addSelectAllHandler(ds.getSelectAllHandler()); + grid.setSelectionMode(SelectionMode.NONE); + grid.setEditorHandler(new TestEditorHandler()); + + sorter = new ListSorter<List<Data>>(grid); + + // Create a bunch of grid columns + + // Data source layout: + // text (String) * (COLUMNS - MANUALLY_FORMATTED_COLUMNS + 1) | + // rownumber (Integer) | some date (Date) | row number as HTML (String) + // | random value (Integer) + + int col = 0; + + // Text times COLUMNS - MANUALLY_FORMATTED_COLUMNS + for (col = 0; col < COLUMNS - MANUALLY_FORMATTED_COLUMNS; ++col) { + + final int c = col; + + Grid.Column<String, List<Data>> column = new Grid.Column<String, List<Data>>( + createRenderer(Renderers.TEXT_RENDERER)) { + @Override + public String getValue(List<Data> row) { + return (String) row.get(c).value; + } + }; + + column.setWidth(50 + c * 25); + column.setHeaderCaption("Header (0," + c + ")"); + + grid.addColumn(column); + } + + // Integer row number + { + final int c = col++; + Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>( + createRenderer(Renderers.NUMBER_RENDERER)) { + @Override + public Integer getValue(List<Data> row) { + return (Integer) row.get(c).value; + } + }; + grid.addColumn(column); + column.setHeaderCaption("Header (0," + c + ")"); + } + + // Some date + { + final int c = col++; + Grid.Column<Date, List<Data>> column = new Grid.Column<Date, List<Data>>( + createRenderer(Renderers.DATE_RENDERER)) { + @Override + public Date getValue(List<Data> row) { + return (Date) row.get(c).value; + } + }; + grid.addColumn(column); + column.setHeaderCaption("Header (0," + c + ")"); + } + + // Row number as a HTML string + { + final int c = col++; + Grid.Column<String, List<Data>> column = new Grid.Column<String, List<Data>>( + createRenderer(Renderers.HTML_RENDERER)) { + @Override + public String getValue(List<Data> row) { + return (String) row.get(c).value; + } + }; + grid.addColumn(column); + column.setHeaderCaption("Header (0," + c + ")"); + } + + // Random integer value + { + final int c = col++; + Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>( + createRenderer(Renderers.NUMBER_RENDERER)) { + @Override + public Integer getValue(List<Data> row) { + return (Integer) row.get(c).value; + } + }; + grid.addColumn(column); + column.setHeaderCaption("Header (0," + c + ")"); + } + + // Random integer value between 0 and 5 + { + final int c = col++; + Grid.Column<Integer, List<Data>> column = new Grid.Column<Integer, List<Data>>( + createRenderer(Renderers.NUMBER_RENDERER)) { + @Override + public Integer getValue(List<Data> row) { + return (Integer) row.get(c).value; + } + }; + grid.addColumn(column); + column.setHeaderCaption("Header (0," + c + ")"); + } + + HeaderRow row = grid.getDefaultHeaderRow(); + for (int i = 0; i < col; ++i) { + String caption = "Header (0," + i + ")"; + Grid.Column<?, ?> column = grid.getColumn(i); + // Lets use some different cell types + if (i % 3 == 0) { + // No-op + } else if (i % 2 == 0) { + row.getCell(column).setHtml("<b>" + caption + "</b>"); + } else { + row.getCell(column).setWidget(new HTML(caption)); + } + } + ++headerCounter; + + // + // Populate the menu + // + + createStateMenu(); + createColumnsMenu(); + createHeaderMenu(); + createFooterMenu(); + createEditorMenu(); + createInternalsMenu(); + createDataSourceMenu(); + + grid.getElement().getStyle().setZIndex(0); + + // + // Composite wrapping for grid. + // + boolean isComposite = Window.Location.getParameter("composite") != null; + if (isComposite) { + addNorth(new Composite() { + { + initWidget(grid); + } + }, 400); + } else { + addNorth(grid, 400); + } + + createKeyHandlers(); + } + + private void createInternalsMenu() { + String[] listenersPath = { "Component", "Internals", "Listeners" }; + final Label label = new Label(); + addSouth(label, 20); + + addMenuCommand("Add scroll listener", new ScheduledCommand() { + private HandlerRegistration scrollHandler = null; + + @Override + public void execute() { + if (scrollHandler != null) { + return; + } + scrollHandler = grid.addScrollHandler(new ScrollHandler() { + @Override + public void onScroll(ScrollEvent event) { + @SuppressWarnings("hiding") + final Grid<?> grid = (Grid<?>) event.getSource(); + label.setText("scrollTop: " + grid.getScrollTop() + + ", scrollLeft: " + grid.getScrollLeft()); + } + }); + } + }, listenersPath); + } + + private void createStateMenu() { + String[] selectionModePath = { "Component", "State", "Selection mode" }; + String[] primaryStyleNamePath = { "Component", "State", + "Primary Stylename" }; + String[] rowStyleGeneratorNamePath = { "Component", "State", + "Row style generator" }; + String[] cellStyleGeneratorNamePath = { "Component", "State", + "Cell style generator" }; + + addMenuCommand("multi", new ScheduledCommand() { + @Override + public void execute() { + grid.setSelectionMode(SelectionMode.MULTI); + } + }, selectionModePath); + + addMenuCommand("single", new ScheduledCommand() { + @Override + public void execute() { + grid.setSelectionMode(SelectionMode.SINGLE); + } + }, selectionModePath); + + addMenuCommand("none", new ScheduledCommand() { + @Override + public void execute() { + grid.setSelectionMode(SelectionMode.NONE); + } + }, selectionModePath); + + addMenuCommand("v-grid", new ScheduledCommand() { + @Override + public void execute() { + grid.setStylePrimaryName("v-grid"); + + } + }, primaryStyleNamePath); + + addMenuCommand("v-escalator", new ScheduledCommand() { + @Override + public void execute() { + grid.setStylePrimaryName("v-escalator"); + + } + }, primaryStyleNamePath); + + addMenuCommand("v-custom-style", new ScheduledCommand() { + @Override + public void execute() { + grid.setStylePrimaryName("v-custom-style"); + + } + }, primaryStyleNamePath); + + addMenuCommand("Edit and refresh Row 0", new ScheduledCommand() { + @Override + public void execute() { + DataSource<List<Data>> ds = grid.getDataSource(); + RowHandle<List<Data>> rowHandle = ds.getHandle(ds.getRow(0)); + rowHandle.getRow().get(0).value = "Foo"; + rowHandle.updateRow(); + } + }, "Component", "State"); + + addMenuCommand("Delayed edit of Row 0", new ScheduledCommand() { + @Override + public void execute() { + DataSource<List<Data>> ds = grid.getDataSource(); + final RowHandle<List<Data>> rowHandle = ds.getHandle(ds + .getRow(0)); + + new Timer() { + @Override + public void run() { + rowHandle.getRow().get(0).value = "Bar"; + rowHandle.updateRow(); + } + + }.schedule(5000); + } + }, "Component", "State"); + + addMenuCommand(ROW_STYLE_GENERATOR_NONE, new ScheduledCommand() { + @Override + public void execute() { + grid.setRowStyleGenerator(null); + } + }, rowStyleGeneratorNamePath); + + addMenuCommand(ROW_STYLE_GENERATOR_EVERY_THIRD, new ScheduledCommand() { + @Override + public void execute() { + grid.setRowStyleGenerator(new RowStyleGenerator<List<Data>>() { + + @Override + public String getStyle(RowReference<List<Data>> rowReference) { + if (rowReference.getRowIndex() % 3 == 0) { + return "third"; + } else { + // First manual col is integer + Integer value = (Integer) rowReference.getRow() + .get(COLUMNS - MANUALLY_FORMATTED_COLUMNS).value; + return value.toString(); + } + } + }); + + } + }, rowStyleGeneratorNamePath); + + addMenuCommand(ROW_STYLE_GENERATOR_ROW_INDEX, new ScheduledCommand() { + @Override + public void execute() { + grid.setRowStyleGenerator(new RowStyleGenerator<List<Data>>() { + + @Override + public String getStyle(RowReference<List<Data>> rowReference) { + return Integer.toString(rowReference.getRowIndex()); + } + }); + + } + }, rowStyleGeneratorNamePath); + + addMenuCommand(CELL_STYLE_GENERATOR_NONE, new ScheduledCommand() { + @Override + public void execute() { + grid.setCellStyleGenerator(null); + } + }, cellStyleGeneratorNamePath); + + addMenuCommand(CELL_STYLE_GENERATOR_SIMPLE, new ScheduledCommand() { + @Override + public void execute() { + grid.setCellStyleGenerator(new CellStyleGenerator<List<Data>>() { + + @Override + public String getStyle( + CellReference<List<Data>> cellReference) { + Grid.Column<?, List<Data>> column = cellReference + .getColumn(); + if (column == grid.getColumn(2)) { + return "two"; + } else if (column == grid.getColumn(COLUMNS + - MANUALLY_FORMATTED_COLUMNS)) { + // First manual col is integer + Integer value = (Integer) column + .getValue(cellReference.getRow()); + return value.toString(); + + } else { + return null; + } + } + }); + } + }, cellStyleGeneratorNamePath); + addMenuCommand(CELL_STYLE_GENERATOR_COL_INDEX, new ScheduledCommand() { + @Override + public void execute() { + grid.setCellStyleGenerator(new CellStyleGenerator<List<Data>>() { + + @Override + public String getStyle( + CellReference<List<Data>> cellReference) { + return cellReference.getRowIndex() + + "_" + + grid.getColumns().indexOf( + cellReference.getColumn()); + } + }); + } + }, cellStyleGeneratorNamePath); + + for (int i = -1; i <= COLUMNS; i++) { + final int index = i; + // Including dummy "columns" prefix because TB fails to select item + // if it's too narrow + addMenuCommand(Integer.toString(index) + " columns", + new ScheduledCommand() { + @Override + public void execute() { + grid.setFrozenColumnCount(index); + } + }, "Component", "State", "Frozen column count"); + } + + addMenuCommand("Enabled", new ScheduledCommand() { + + @Override + public void execute() { + grid.setEnabled(!grid.isEnabled()); + } + }, "Component", "State"); + } + + private void createColumnsMenu() { + + for (int i = 0; i < COLUMNS; i++) { + final int index = i; + final Grid.Column<?, List<Data>> column = grid.getColumn(index); + addMenuCommand("Sortable", new ScheduledCommand() { + @Override + public void execute() { + column.setSortable(!column.isSortable()); + } + }, "Component", "Columns", "Column " + i); + + addMenuCommand("auto", new ScheduledCommand() { + @Override + public void execute() { + column.setWidth(-1); + } + }, "Component", "Columns", "Column " + i, "Width"); + addMenuCommand("50px", new ScheduledCommand() { + @Override + public void execute() { + column.setWidth(50); + } + }, "Component", "Columns", "Column " + i, "Width"); + addMenuCommand("200px", new ScheduledCommand() { + @Override + public void execute() { + column.setWidth(200); + } + }, "Component", "Columns", "Column " + i, "Width"); + + // Header types + addMenuCommand("Text Header", new ScheduledCommand() { + @Override + public void execute() { + column.setHeaderCaption("Text Header"); + } + }, "Component", "Columns", "Column " + i, "Header Type"); + addMenuCommand("HTML Header", new ScheduledCommand() { + @Override + public void execute() { + grid.getHeaderRow(0).getCell(column) + .setHtml("<b>HTML Header</b>"); + } + }, "Component", "Columns", "Column " + i, "Header Type"); + addMenuCommand("Widget Header", new ScheduledCommand() { + @Override + public void execute() { + final Button button = new Button("Button Header"); + button.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + button.setText("Clicked"); + } + }); + grid.getHeaderRow(0).getCell(column).setWidget(button); + } + }, "Component", "Columns", "Column " + i, "Header Type"); + + // Footer types + addMenuCommand("Text Footer", new ScheduledCommand() { + @Override + public void execute() { + grid.getFooterRow(0).getCell(column).setText("Text Footer"); + } + }, "Component", "Columns", "Column " + i, "Footer Type"); + addMenuCommand("HTML Footer", new ScheduledCommand() { + @Override + public void execute() { + grid.getFooterRow(0).getCell(column) + .setHtml("<b>HTML Footer</b>"); + } + }, "Component", "Columns", "Column " + i, "Footer Type"); + addMenuCommand("Widget Footer", new ScheduledCommand() { + @Override + public void execute() { + final Button button = new Button("Button Footer"); + button.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + button.setText("Clicked"); + } + }); + grid.getFooterRow(0).getCell(column).setWidget(button); + } + }, "Component", "Columns", "Column " + i, "Footer Type"); + + // Renderer throwing exceptions + addMenuCommand("Broken renderer", new ScheduledCommand() { + @Override + public void execute() { + final Renderer<Object> originalRenderer = (Renderer<Object>) column + .getRenderer(); + + column.setRenderer(new Renderer<Object>() { + @Override + public void render(RendererCellReference cell, + Object data) { + if (cell.getRowIndex() == cell.getColumnIndex()) { + throw new RuntimeException("I'm broken"); + } + originalRenderer.render(cell, data); + } + }); + } + }, "Component", "Columns", "Column " + i); + } + } + + private int headerCounter = 0; + private int footerCounter = 0; + + private void setHeaderTexts(HeaderRow row) { + for (int i = 0; i < COLUMNS; ++i) { + String caption = "Header (" + headerCounter + "," + i + ")"; + + // Lets use some different cell types + if (i % 3 == 0) { + row.getCell(grid.getColumn(i)).setText(caption); + } else if (i % 2 == 0) { + row.getCell(grid.getColumn(i)) + .setHtml("<b>" + caption + "</b>"); + } else { + row.getCell(grid.getColumn(i)).setWidget(new HTML(caption)); + } + } + headerCounter++; + } + + private void setFooterTexts(FooterRow row) { + for (int i = 0; i < COLUMNS; ++i) { + String caption = "Footer (" + footerCounter + "," + i + ")"; + + // Lets use some different cell types + if (i % 3 == 0) { + row.getCell(grid.getColumn(i)).setText(caption); + } else if (i % 2 == 0) { + row.getCell(grid.getColumn(i)) + .setHtml("<b>" + caption + "</b>"); + } else { + row.getCell(grid.getColumn(i)).setWidget(new HTML(caption)); + } + } + footerCounter++; + } + + private void createHeaderMenu() { + final String[] menuPath = { "Component", "Header" }; + + addMenuCommand("Visible", new ScheduledCommand() { + @Override + public void execute() { + grid.setHeaderVisible(!grid.isHeaderVisible()); + } + }, menuPath); + + addMenuCommand("Top", new ScheduledCommand() { + @Override + public void execute() { + grid.setDefaultHeaderRow(grid.getHeaderRow(0)); + } + }, "Component", "Header", "Default row"); + addMenuCommand("Bottom", new ScheduledCommand() { + @Override + public void execute() { + grid.setDefaultHeaderRow(grid.getHeaderRow(grid + .getHeaderRowCount() - 1)); + } + }, "Component", "Header", "Default row"); + addMenuCommand("Unset", new ScheduledCommand() { + @Override + public void execute() { + grid.setDefaultHeaderRow(null); + } + }, "Component", "Header", "Default row"); + + addMenuCommand("Prepend row", new ScheduledCommand() { + @Override + public void execute() { + configureHeaderRow(grid.prependHeaderRow()); + } + }, menuPath); + addMenuCommand("Append row", new ScheduledCommand() { + @Override + public void execute() { + configureHeaderRow(grid.appendHeaderRow()); + } + }, menuPath); + addMenuCommand("Remove top row", new ScheduledCommand() { + @Override + public void execute() { + grid.removeHeaderRow(0); + } + }, menuPath); + addMenuCommand("Remove bottom row", new ScheduledCommand() { + @Override + public void execute() { + grid.removeHeaderRow(grid.getHeaderRowCount() - 1); + } + }, menuPath); + + } + + private void configureHeaderRow(final HeaderRow row) { + setHeaderTexts(row); + String rowTitle = "Row " + grid.getHeaderRowCount(); + final String[] menuPath = { "Component", "Header", rowTitle }; + + addMenuCommand("Join column cells 0, 1", new ScheduledCommand() { + + @Override + public void execute() { + row.join(row.getCell(grid.getColumn(0)), + row.getCell(grid.getColumn(1))).setText( + "Join column cells 0, 1"); + + } + }, menuPath); + + addMenuCommand("Join columns 1, 2", new ScheduledCommand() { + + @Override + public void execute() { + row.join(grid.getColumn(1), grid.getColumn(2)).setText( + "Join columns 1, 2"); + ; + + } + }, menuPath); + + addMenuCommand("Join columns 3, 4, 5", new ScheduledCommand() { + + @Override + public void execute() { + row.join(grid.getColumn(3), grid.getColumn(4), + grid.getColumn(5)).setText("Join columns 3, 4, 5"); + + } + }, menuPath); + + addMenuCommand("Join all columns", new ScheduledCommand() { + + @Override + public void execute() { + row.join( + grid.getColumns().toArray( + new Grid.Column[grid.getColumnCount()])) + .setText("Join all columns"); + ; + + } + }, menuPath); + } + + private void createFooterMenu() { + final String[] menuPath = { "Component", "Footer" }; + + addMenuCommand("Visible", new ScheduledCommand() { + @Override + public void execute() { + grid.setFooterVisible(!grid.isFooterVisible()); + } + }, menuPath); + + addMenuCommand("Prepend row", new ScheduledCommand() { + @Override + public void execute() { + configureFooterRow(grid.prependFooterRow()); + } + }, menuPath); + addMenuCommand("Append row", new ScheduledCommand() { + @Override + public void execute() { + configureFooterRow(grid.appendFooterRow()); + } + }, menuPath); + addMenuCommand("Remove top row", new ScheduledCommand() { + @Override + public void execute() { + grid.removeFooterRow(0); + } + }, menuPath); + addMenuCommand("Remove bottom row", new ScheduledCommand() { + @Override + public void execute() { + assert grid.getFooterRowCount() > 0; + grid.removeFooterRow(grid.getFooterRowCount() - 1); + } + }, menuPath); + } + + private void createEditorMenu() { + addMenuCommand("Enabled", new ScheduledCommand() { + @Override + public void execute() { + grid.setEditorEnabled(!grid.isEditorEnabled()); + } + }, "Component", "Editor"); + + addMenuCommand("Edit row 5", new ScheduledCommand() { + @Override + public void execute() { + grid.editRow(5); + } + }, "Component", "Editor"); + + addMenuCommand("Edit row 100", new ScheduledCommand() { + @Override + public void execute() { + grid.editRow(100); + } + }, "Component", "Editor"); + + addMenuCommand("Save", new ScheduledCommand() { + @Override + public void execute() { + grid.saveEditor(); + } + }, "Component", "Editor"); + + addMenuCommand("Cancel edit", new ScheduledCommand() { + @Override + public void execute() { + grid.cancelEditor(); + } + }, "Component", "Editor"); + + } + + private void configureFooterRow(final FooterRow row) { + setFooterTexts(row); + String rowTitle = "Row " + grid.getFooterRowCount(); + final String[] menuPath = { "Component", "Footer", rowTitle }; + + addMenuCommand("Join column cells 0, 1", new ScheduledCommand() { + + @Override + public void execute() { + row.join(row.getCell(grid.getColumn(0)), + row.getCell(grid.getColumn(1))).setText( + "Join column cells 0, 1"); + + } + }, menuPath); + + addMenuCommand("Join columns 1, 2", new ScheduledCommand() { + + @Override + public void execute() { + row.join(grid.getColumn(1), grid.getColumn(2)).setText( + "Join columns 1, 2"); + ; + + } + }, menuPath); + + addMenuCommand("Join all columns", new ScheduledCommand() { + + @Override + public void execute() { + row.join( + grid.getColumns().toArray( + new Grid.Column[grid.getColumnCount()])) + .setText("Join all columns"); + ; + + } + }, menuPath); + } + + private void createDataSourceMenu() { + final String[] menuPath = { "Component", "DataSource" }; + + addMenuCommand("Reset with 100 rows of Data", new ScheduledCommand() { + @Override + public void execute() { + ds.asList().clear(); + data = createData(100); + ds.asList().addAll(data); + } + }, menuPath); + + addMenuCommand("Reset with " + ROWS + " rows of Data", + new ScheduledCommand() { + @Override + public void execute() { + ds.asList().clear(); + data = createData(ROWS); + ds.asList().addAll(data); + } + }, menuPath); + } + + /** + * Creates a renderer for a {@link Renderers} + */ + @SuppressWarnings("rawtypes") + private final Renderer createRenderer(Renderers renderer) { + switch (renderer) { + case TEXT_RENDERER: + return new TextRenderer(); + + case HTML_RENDERER: + return new HtmlRenderer() { + + @Override + public void render(RendererCellReference cell, String htmlString) { + super.render(cell, "<b>" + htmlString + "</b>"); + } + }; + + case NUMBER_RENDERER: + return new NumberRenderer(); + + case DATE_RENDERER: + return new DateRenderer(); + + default: + return new TextRenderer(); + } + } + + /** + * Creates a collection of handlers for all the grid key events + */ + private void createKeyHandlers() { + final List<VLabel> labels = new ArrayList<VLabel>(); + for (int i = 0; i < 9; ++i) { + VLabel tmp = new VLabel(); + addNorth(tmp, 20); + labels.add(tmp); + } + + // Key Down Events + grid.addBodyKeyDownHandler(new BodyKeyDownHandler() { + private final VLabel label = labels.get(0); + + @Override + public void onKeyDown(GridKeyDownEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + grid.addHeaderKeyDownHandler(new HeaderKeyDownHandler() { + private final VLabel label = labels.get(1); + + @Override + public void onKeyDown(GridKeyDownEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + grid.addFooterKeyDownHandler(new FooterKeyDownHandler() { + private final VLabel label = labels.get(2); + + @Override + public void onKeyDown(GridKeyDownEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + // Key Up Events + grid.addBodyKeyUpHandler(new BodyKeyUpHandler() { + private final VLabel label = labels.get(3); + + @Override + public void onKeyUp(GridKeyUpEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + grid.addHeaderKeyUpHandler(new HeaderKeyUpHandler() { + private final VLabel label = labels.get(4); + + @Override + public void onKeyUp(GridKeyUpEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + grid.addFooterKeyUpHandler(new FooterKeyUpHandler() { + private final VLabel label = labels.get(5); + + @Override + public void onKeyUp(GridKeyUpEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + // Key Press Events + grid.addBodyKeyPressHandler(new BodyKeyPressHandler() { + private final VLabel label = labels.get(6); + + @Override + public void onKeyPress(GridKeyPressEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + grid.addHeaderKeyPressHandler(new HeaderKeyPressHandler() { + private final VLabel label = labels.get(7); + + @Override + public void onKeyPress(GridKeyPressEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + grid.addFooterKeyPressHandler(new FooterKeyPressHandler() { + private final VLabel label = labels.get(8); + + @Override + public void onKeyPress(GridKeyPressEvent event) { + CellReference<?> focused = event.getFocusedCell(); + updateLabel(label, event.toDebugString(), + focused.getRowIndex(), focused.getColumnIndex()); + } + }); + + } + + private void updateLabel(VLabel label, String output, int object, int column) { + String coords = "(" + object + ", " + column + ")"; + label.setText(coords + " " + output); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java new file mode 100644 index 0000000000..f35f9820e0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererConnector.java @@ -0,0 +1,386 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Element; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.Timer; +import com.google.gwt.user.client.Window.Location; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.HasWidgets; +import com.vaadin.client.data.DataChangeHandler; +import com.vaadin.client.data.DataSource; +import com.vaadin.client.renderers.ComplexRenderer; +import com.vaadin.client.renderers.DateRenderer; +import com.vaadin.client.renderers.HtmlRenderer; +import com.vaadin.client.renderers.NumberRenderer; +import com.vaadin.client.renderers.Renderer; +import com.vaadin.client.renderers.TextRenderer; +import com.vaadin.client.renderers.WidgetRenderer; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.client.widget.grid.CellReference; +import com.vaadin.client.widget.grid.RendererCellReference; +import com.vaadin.client.widget.grid.datasources.ListDataSource; +import com.vaadin.client.widget.grid.datasources.ListSorter; +import com.vaadin.client.widget.grid.sort.Sort; +import com.vaadin.client.widget.grid.sort.SortEvent; +import com.vaadin.client.widget.grid.sort.SortHandler; +import com.vaadin.client.widget.grid.sort.SortOrder; +import com.vaadin.client.widgets.Grid; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.widgetset.server.grid.GridClientColumnRenderers; + +@Connect(GridClientColumnRenderers.GridController.class) +public class GridClientColumnRendererConnector extends + AbstractComponentConnector { + + public static enum Renderers { + TEXT_RENDERER, WIDGET_RENDERER, HTML_RENDERER, NUMBER_RENDERER, DATE_RENDERER, CPLX_RENDERER; + } + + /** + * Datasource for simulating network latency + */ + private class DelayedDataSource implements DataSource<String> { + + private DataSource<String> ds; + private int firstRowIndex = -1; + private int numberOfRows; + private DataChangeHandler dataChangeHandler; + private int latency; + + public DelayedDataSource(DataSource<String> ds, int latency) { + this.ds = ds; + this.latency = latency; + } + + @Override + public void ensureAvailability(final int firstRowIndex, + final int numberOfRows) { + new Timer() { + + @Override + public void run() { + DelayedDataSource.this.firstRowIndex = firstRowIndex; + DelayedDataSource.this.numberOfRows = numberOfRows; + dataChangeHandler.dataUpdated(firstRowIndex, numberOfRows); + dataChangeHandler + .dataAvailable(firstRowIndex, numberOfRows); + } + }.schedule(latency); + } + + @Override + public String getRow(int rowIndex) { + if (rowIndex >= firstRowIndex + && rowIndex <= firstRowIndex + numberOfRows) { + return ds.getRow(rowIndex); + } + return null; + } + + @Override + public int size() { + return ds.size(); + } + + @Override + public void setDataChangeHandler(DataChangeHandler dataChangeHandler) { + this.dataChangeHandler = dataChangeHandler; + } + + @Override + public RowHandle<String> getHandle(String row) { + // TODO Auto-generated method stub (henrik paul: 17.6.) + return null; + } + + @Override + public int indexOf(String row) { + return ds.indexOf(row); + } + } + + @Override + protected void init() { + Grid<String> grid = getWidget(); + grid.setSelectionMode(Grid.SelectionMode.NONE); + + // Generated some column data + List<String> columnData = new ArrayList<String>(); + for (int i = 0; i < 100; i++) { + columnData.add(String.valueOf(i)); + } + + // Provide data as data source + if (Location.getParameter("latency") != null) { + grid.setDataSource(new DelayedDataSource( + new ListDataSource<String>(columnData), Integer + .parseInt(Location.getParameter("latency")))); + } else { + grid.setDataSource(new ListDataSource<String>(columnData)); + } + + // Add a column to display the data in + Grid.Column<String, String> c = createColumnWithRenderer(Renderers.TEXT_RENDERER); + grid.addColumn(c); + grid.getDefaultHeaderRow().getCell(c).setText("Column 1"); + + // Add another column with a custom complex renderer + c = createColumnWithRenderer(Renderers.CPLX_RENDERER); + grid.addColumn(c); + grid.getDefaultHeaderRow().getCell(c).setText("Column 2"); + + // Add method for testing sort event firing + grid.addSortHandler(new SortHandler<String>() { + @Override + public void sort(SortEvent<String> event) { + Element console = Document.get().getElementById( + "testDebugConsole"); + String text = "Client-side sort event received<br>" + + "Columns: " + event.getOrder().size() + ", order: "; + for (SortOrder order : event.getOrder()) { + String columnHeader = getWidget().getDefaultHeaderRow() + .getCell(order.getColumn()).getText(); + text += columnHeader + ": " + + order.getDirection().toString(); + } + console.setInnerHTML(text); + } + }); + + // Handle RPC calls + registerRpc(GridClientColumnRendererRpc.class, + new GridClientColumnRendererRpc() { + + @Override + public void addColumn(Renderers renderer) { + + Grid.Column<?, String> column; + if (renderer == Renderers.NUMBER_RENDERER) { + column = createNumberColumnWithRenderer(renderer); + } else if (renderer == Renderers.DATE_RENDERER) { + column = createDateColumnWithRenderer(renderer); + } else { + column = createColumnWithRenderer(renderer); + } + getWidget().addColumn(column); + + getWidget() + .getDefaultHeaderRow() + .getCell(column) + .setText( + "Column " + + String.valueOf(getWidget() + .getColumnCount() + 1)); + } + + @Override + public void detachAttach() { + + // Detach + HasWidgets parent = (HasWidgets) getWidget() + .getParent(); + parent.remove(getWidget()); + + // Re-attach + parent.add(getWidget()); + } + + @Override + public void triggerClientSorting() { + getWidget().sort(Sort.by(getWidget().getColumn(0))); + } + + @Override + @SuppressWarnings("unchecked") + public void triggerClientSortingTest() { + Grid<String> grid = getWidget(); + ListSorter<String> sorter = new ListSorter<String>(grid); + + // Make sorter sort the numbers in natural order + sorter.setComparator( + (Grid.Column<String, String>) grid.getColumn(0), + new Comparator<String>() { + @Override + public int compare(String o1, String o2) { + return Integer.parseInt(o1) + - Integer.parseInt(o2); + } + }); + + // Sort along column 0 in ascending order + grid.sort(grid.getColumn(0)); + + // Remove the sorter once we're done + sorter.removeFromGrid(); + } + + @Override + @SuppressWarnings("unchecked") + public void shuffle() { + Grid<String> grid = getWidget(); + ListSorter<String> shuffler = new ListSorter<String>( + grid); + + // Make shuffler return random order + shuffler.setComparator( + (Grid.Column<String, String>) grid.getColumn(0), + new Comparator<String>() { + @Override + public int compare(String o1, String o2) { + return com.google.gwt.user.client.Random + .nextInt(3) - 1; + } + }); + + // "Sort" (actually shuffle) along column 0 + grid.sort(grid.getColumn(0)); + + // Remove the shuffler when we're done so that it + // doesn't interfere with further operations + shuffler.removeFromGrid(); + } + }); + } + + /** + * Creates a a renderer for a {@link Renderers} + */ + private Renderer createRenderer(Renderers renderer) { + switch (renderer) { + case TEXT_RENDERER: + return new TextRenderer(); + + case WIDGET_RENDERER: + return new WidgetRenderer<String, Button>() { + + @Override + public Button createWidget() { + final Button button = new Button(""); + button.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + button.setText("Clicked"); + } + }); + return button; + } + + @Override + public void render(RendererCellReference cell, String data, + Button button) { + button.setHTML(data); + } + }; + + case HTML_RENDERER: + return new HtmlRenderer() { + + @Override + public void render(RendererCellReference cell, String htmlString) { + super.render(cell, "<b>" + htmlString + "</b>"); + } + }; + + case NUMBER_RENDERER: + return new NumberRenderer(); + + case DATE_RENDERER: + return new DateRenderer(); + + case CPLX_RENDERER: + return new ComplexRenderer<String>() { + + @Override + public void init(RendererCellReference cell) { + } + + @Override + public void render(RendererCellReference cell, String data) { + cell.getElement().setInnerHTML("<span>" + data + "</span>"); + cell.getElement().getStyle().clearBackgroundColor(); + } + + @Override + public void setContentVisible(RendererCellReference cell, + boolean hasData) { + + // Visualize content visible property + cell.getElement().getStyle() + .setBackgroundColor(hasData ? "green" : "red"); + + super.setContentVisible(cell, hasData); + } + + @Override + public boolean onActivate(CellReference<?> cell) { + cell.getElement().setInnerHTML("<span>Activated!</span>"); + return true; + } + }; + + default: + return new TextRenderer(); + } + } + + private Grid.Column<String, String> createColumnWithRenderer( + Renderers renderer) { + return new Grid.Column<String, String>(createRenderer(renderer)) { + + @Override + public String getValue(String row) { + return row; + } + }; + } + + private Grid.Column<Number, String> createNumberColumnWithRenderer( + Renderers renderer) { + return new Grid.Column<Number, String>(createRenderer(renderer)) { + + @Override + public Number getValue(String row) { + return Long.parseLong(row); + } + }; + } + + private Grid.Column<Date, String> createDateColumnWithRenderer( + Renderers renderer) { + return new Grid.Column<Date, String>(createRenderer(renderer)) { + + @Override + public Date getValue(String row) { + return new Date(); + } + }; + } + + @Override + public Grid<String> getWidget() { + return (Grid<String>) super.getWidget(); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererRpc.java new file mode 100644 index 0000000000..90eee9e1c6 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientColumnRendererRpc.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import com.vaadin.shared.communication.ClientRpc; +import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererConnector.Renderers; + +public interface GridClientColumnRendererRpc extends ClientRpc { + + /** + * Adds a new column with a specific renderer to the grid + * + */ + void addColumn(Renderers renderer); + + /** + * Detaches and attaches the client side Grid + */ + void detachAttach(); + + /** + * Used for client-side sorting API test + */ + void triggerClientSorting(); + + /** + * @since + */ + void triggerClientSortingTest(); + + /** + * @since + */ + void shuffle(); +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientDataSourcesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientDataSourcesWidget.java new file mode 100644 index 0000000000..e352b10064 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridClientDataSourcesWidget.java @@ -0,0 +1,219 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.vaadin.client.data.AbstractRemoteDataSource; +import com.vaadin.client.renderers.TextRenderer; +import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.SelectionMode; + +public class GridClientDataSourcesWidget extends + PureGWTTestApplication<Grid<String[]>> { + + private interface RestCallback { + void onResponse(RestishDataSource.Backend.Result result); + } + + /** + * This is an emulated datasource that has a back-end that changes size + * constantly. The back-end is unable to actively push data to Grid. + * Instead, with each row request, in addition to its row payload it tells + * how many rows it contains in total. + * + * A plausible response from this REST-like api would be: + * + * <pre> + * <code> + * GET /foos/4..8 + * + * { + * "resultsize": 4, + * "data": [ + * [4, "foo IV"], + * [5, "foo V"], + * [6, "foo VI"] + * [7, "foo VII"] + * ], + * "totalrows": 100 + * } + * </code> + * </pre> + * + * In this case, the size of Grid needs to be updated to be able to show 100 + * rows in total (no more, no less). + * + * This class + * <ol> + * <li>gets initialized + * <li>asks for its size + * <li>updates Grid once the reply is received + * <li>as the Grid fetches more data, the total row count is dynamically + * updated. + * </ol> + */ + private class RestishDataSource extends AbstractRemoteDataSource<String[]> { + /** + * Pretend like this class doesn't exist. It just simulates a backend + * somewhere. + * <p> + * It's scoped inside the RDS class only because it's tied to that. + * */ + private class Backend { + public class Result { + public int size; + public List<String[]> rows; + } + + private int size = 200; + private int modCount = 0; + + public void query(int firstRowIndex, int numberOfRows, + final RestCallback callback) { + final Result result = new Result(); + result.size = size; + result.rows = fetchRows(firstRowIndex, numberOfRows); + + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + callback.onResponse(result); + } + }); + + } + + private List<String[]> fetchRows(int firstRowIndex, int numberOfRows) { + List<String[]> rows = new ArrayList<String[]>(); + for (int i = 0; i < numberOfRows; i++) { + String id = String.valueOf(firstRowIndex + i); + rows.add(new String[] { id, "cell " + id + " #" + modCount }); + } + return rows; + } + + public void pushRowChanges(int rows) { + size += rows; + pushRowChanges(); + } + + public void pushRowChanges() { + modCount++; + + // push "something happened" to datasource "over the wire": + resetDataAndSize(size); + } + + public void addRows(int rowcount) { + modCount++; + size += rowcount; + } + } + + final Backend backend; + + public RestishDataSource() { + backend = new Backend(); + } + + @Override + protected void requestRows(int firstRowIndex, int numberOfRows, + final RequestRowsCallback<String[]> callback) { + + backend.query(firstRowIndex, numberOfRows, new RestCallback() { + @Override + public void onResponse(Backend.Result result) { + callback.onResponse(result.rows, result.size); + } + }); + } + + @Override + public Object getRowKey(String[] row) { + return row[0]; + } + } + + private final Grid<String[]> grid; + + private RestishDataSource restishDataSource; + + private final ScheduledCommand setRestishCommand = new ScheduledCommand() { + @Override + public void execute() { + for (Grid.Column<?, String[]> column : grid.getColumns()) { + grid.removeColumn(column); + } + + restishDataSource = new RestishDataSource(); + grid.setDataSource(restishDataSource); + grid.addColumn(new Grid.Column<String, String[]>("column", + new TextRenderer()) { + + @Override + public String getValue(String[] row) { + return row[1]; + } + }); + } + }; + + public GridClientDataSourcesWidget() { + super(new Grid<String[]>()); + grid = getTestedWidget(); + + grid.getElement().getStyle().setZIndex(0); + grid.setHeight("400px"); + grid.setSelectionMode(SelectionMode.NONE); + addNorth(grid, 400); + + addMenuCommand("Use", setRestishCommand, "DataSources", "RESTish"); + addMenuCommand("Next request +10", new ScheduledCommand() { + @Override + public void execute() { + restishDataSource.backend.addRows(10); + } + }, "DataSources", "RESTish"); + addMenuCommand("Next request -10", new ScheduledCommand() { + @Override + public void execute() { + restishDataSource.backend.addRows(-10); + } + }, "DataSources", "RESTish"); + addMenuCommand("Push data change", new ScheduledCommand() { + @Override + public void execute() { + restishDataSource.backend.pushRowChanges(); + } + }, "DataSources", "RESTish"); + addMenuCommand("Push data change +10", new ScheduledCommand() { + @Override + public void execute() { + restishDataSource.backend.pushRowChanges(10); + } + }, "DataSources", "RESTish"); + addMenuCommand("Push data change -10", new ScheduledCommand() { + @Override + public void execute() { + restishDataSource.backend.pushRowChanges(-10); + } + }, "DataSources", "RESTish"); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientWidget.java new file mode 100644 index 0000000000..caaed12e70 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridColumnAutoWidthClientWidget.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.vaadin.client.renderers.HtmlRenderer; +import com.vaadin.client.widget.grid.datasources.ListDataSource; +import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.SelectionMode; + +public class GridColumnAutoWidthClientWidget extends + PureGWTTestApplication<Grid<List<String>>> { + + private Grid<List<String>> grid; + + private class Col extends Grid.Column<String, List<String>> { + public Col(String header) { + super(header, new HtmlRenderer()); + setExpandRatio(0); + } + + @Override + public String getValue(List<String> row) { + int index = grid.getColumns().indexOf(this); + return "<span>" + String.valueOf(row.get(index)) + "</span>"; + } + } + + public GridColumnAutoWidthClientWidget() { + super(new Grid<List<String>>()); + grid = getTestedWidget(); + grid.setSelectionMode(SelectionMode.NONE); + grid.setWidth("700px"); + + List<List<String>> list = new ArrayList<List<String>>(); + list.add(Arrays.asList("equal length", "a very long cell content", + "short", "fixed width narrow", "fixed width wide")); + grid.setDataSource(new ListDataSource<List<String>>(list)); + + addColumn("equal length"); + addColumn("short"); + addColumn("a very long header content"); + addColumn("fixed width narrow").setWidth(50); + addColumn("fixed width wide").setWidth(200); + + addNorth(grid, 400); + } + + private Col addColumn(String header) { + Col column = grid.addColumn(new Col(header)); + grid.getHeaderRow(0).getCell(column) + .setHtml("<span>" + header + "</span>"); + return column; + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridDefaultTextRendererWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridDefaultTextRendererWidget.java new file mode 100644 index 0000000000..4f1ea48be5 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridDefaultTextRendererWidget.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import com.vaadin.client.widget.grid.datasources.ListDataSource; +import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.Column; +import com.vaadin.client.widgets.Grid.SelectionMode; +import com.vaadin.shared.ui.grid.HeightMode; + +public class GridDefaultTextRendererWidget extends + PureGWTTestApplication<Grid<String>> { + /* + * This can't be null, because grid thinks that a row object of null means + * "data is still being fetched". + */ + private static final String NULL_STRING = ""; + + private Grid<String> grid; + + public GridDefaultTextRendererWidget() { + super(new Grid<String>()); + grid = getTestedWidget(); + + grid.setDataSource(new ListDataSource<String>(NULL_STRING, "string")); + grid.addColumn(new Column<String, String>() { + @Override + public String getValue(String row) { + if (!NULL_STRING.equals(row)) { + return row; + } else { + return null; + } + } + }); + + grid.addColumn(new Column<String, String>() { + + @Override + public String getValue(String row) { + return "foo"; + } + + }); + + grid.setHeightByRows(2); + grid.setHeightMode(HeightMode.ROW); + grid.setSelectionMode(SelectionMode.NONE); + addNorth(grid, 500); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridHeightByRowOnInitWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridHeightByRowOnInitWidget.java new file mode 100644 index 0000000000..8202c2ccc0 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridHeightByRowOnInitWidget.java @@ -0,0 +1,32 @@ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.Arrays; + +import com.google.gwt.user.client.ui.Composite; +import com.google.gwt.user.client.ui.SimplePanel; +import com.vaadin.client.widget.grid.datasources.ListDataSource; +import com.vaadin.client.widgets.Grid; +import com.vaadin.client.widgets.Grid.Column; +import com.vaadin.shared.ui.grid.HeightMode; + +public class GridHeightByRowOnInitWidget extends Composite { + private final SimplePanel panel = new SimplePanel(); + private final Grid<String> grid = new Grid<String>(); + + public GridHeightByRowOnInitWidget() { + initWidget(panel); + + panel.setWidget(grid); + grid.setDataSource(new ListDataSource<String>(Arrays.asList("A", "B", + "C", "D", "E"))); + grid.addColumn(new Column<String, String>("letter") { + @Override + public String getValue(String row) { + return row; + } + }); + + grid.setHeightMode(HeightMode.ROW); + grid.setHeightByRows(5.0d); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java new file mode 100644 index 0000000000..e89057a148 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/IntArrayRendererConnector.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import com.vaadin.client.connectors.AbstractRendererConnector; +import com.vaadin.client.renderers.Renderer; +import com.vaadin.client.widget.grid.RendererCellReference; +import com.vaadin.shared.ui.Connect; + +@Connect(com.vaadin.tests.components.grid.IntArrayRenderer.class) +public class IntArrayRendererConnector extends AbstractRendererConnector<int[]> { + + public static class IntArrayRenderer implements Renderer<int[]> { + private static final String JOINER = " :: "; + + @Override + public void render(RendererCellReference cell, int[] data) { + String text = ""; + for (int i : data) { + text += i + JOINER; + } + if (!text.isEmpty()) { + text = text.substring(0, text.length() - JOINER.length()); + } + cell.getElement().setInnerText(text); + } + } + + @Override + public IntArrayRenderer getRenderer() { + return (IntArrayRenderer) super.getRenderer(); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/PureGWTTestApplication.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/PureGWTTestApplication.java new file mode 100644 index 0000000000..e9c126f232 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/PureGWTTestApplication.java @@ -0,0 +1,308 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.DockLayoutPanel; +import com.google.gwt.user.client.ui.LayoutPanel; +import com.google.gwt.user.client.ui.MenuBar; +import com.google.gwt.user.client.ui.Panel; +import com.vaadin.client.ui.SubPartAware; + +/** + * Pure GWT Test Application base for testing features of a single widget; + * provides a menu system and convenience method for adding items to it. + * + * @since + * @author Vaadin Ltd + */ +public abstract class PureGWTTestApplication<T> extends DockLayoutPanel + implements SubPartAware { + + /** + * Class describing a menu item with an associated action + */ + public static class Command { + private final String title; + private final ScheduledCommand command; + + /** + * Creates a Command object, which is used as an action entry in the + * Menu + * + * @param t + * a title string + * @param cmd + * a scheduled command that is executed when this item is + * selected + */ + public Command(String t, ScheduledCommand cmd) { + title = t; + command = cmd; + } + + /** + * Returns the title of this command item + * + * @return a title string + */ + public final String getTitle() { + return title; + } + + /** + * Returns the actual scheduled command of this command item + * + * @return a scheduled command + */ + public final ScheduledCommand getCommand() { + return command; + } + } + + /** + * A menu object, providing a complete system for building a hierarchical + * menu bar system. + */ + public static class Menu { + + private final String title; + private final MenuBar menubar; + private final List<Menu> children; + private final List<Command> items; + + /** + * Create base-level menu, without a title. This is the root menu bar, + * which can be attached to a client application window. All other Menus + * should be added as child menus to this Menu, in order to maintain a + * nice hierarchy. + */ + private Menu() { + title = ""; + menubar = new MenuBar(); + children = new ArrayList<Menu>(); + items = new ArrayList<Command>(); + } + + /** + * Create a sub-menu, with a title. + * + * @param title + */ + public Menu(String title) { + this.title = title; + menubar = new MenuBar(true); + children = new ArrayList<Menu>(); + items = new ArrayList<Command>(); + } + + /** + * Return the GWT {@link MenuBar} object that provides the widget for + * this Menu + * + * @return a menubar object + */ + public MenuBar getMenuBar() { + return menubar; + } + + /** + * Returns the title of this menu entry + * + * @return a title string + */ + public String getTitle() { + return title; + } + + /** + * Adds a child menu entry to this menu. The title for this entry is + * taken from the Menu object argument. + * + * @param m + * another Menu object + */ + public void addChildMenu(Menu m) { + menubar.addItem(m.title, m.menubar); + children.add(m); + } + + /** + * Tests for the existence of a child menu by title at this level of the + * menu hierarchy + * + * @param title + * a title string + * @return true, if this menu has a direct child menu with the specified + * title, otherwise false + */ + public boolean hasChildMenu(String title) { + return getChildMenu(title) != null; + } + + /** + * Gets a reference to a child menu with a certain title, that is a + * direct child of this menu level. + * + * @param title + * a title string + * @return a Menu object with the specified title string, or null, if + * this menu doesn't have a direct child with the specified + * title. + */ + public Menu getChildMenu(String title) { + for (Menu m : children) { + if (m.title.equals(title)) { + return m; + } + } + return null; + } + + /** + * Adds a command item to the menu. When the entry is clicked, the + * command is executed. + * + * @param cmd + * a command object. + */ + public void addCommand(Command cmd) { + menubar.addItem(cmd.title, cmd.command); + items.add(cmd); + } + + /** + * Tests for the existence of a {@link Command} that is the direct child + * of this level of menu. + * + * @param title + * the command's title + * @return true, if this menu level includes a command item with the + * specified title. Otherwise false. + */ + public boolean hasCommand(String title) { + return getCommand(title) != null; + } + + /** + * Gets a reference to a {@link Command} item that is the direct child + * of this level of menu. + * + * @param title + * the command's title + * @return a command, if found in this menu level, otherwise null. + */ + public Command getCommand(String title) { + for (Command c : items) { + if (c.title.equals(title)) { + return c; + } + } + return null; + } + } + + /** + * Base level menu object, provides visible menu bar + */ + private final Menu menu; + private final T testedWidget; + + /** + * This constructor creates the basic menu bar and adds it to the top of the + * parent {@link DockLayoutPanel} + */ + protected PureGWTTestApplication(T widget) { + super(Unit.PX); + Panel menuPanel = new LayoutPanel(); + menu = new Menu(); + menuPanel.add(menu.getMenuBar()); + addNorth(menuPanel, 25); + testedWidget = widget; + } + + /** + * Connect an item to the menu structure + * + * @param cmd + * a scheduled command; see google's docs + * @param menupath + * path to the item + */ + public void addMenuCommand(String title, ScheduledCommand cmd, + String... menupath) { + Menu m = createMenuPath(menupath); + + m.addCommand(new Command(title, cmd)); + } + + /** + * Create a menu path, if one doesn't already exist, and return the last + * menu in the series. + * + * @param path + * a varargs list or array of strings describing a menu path, + * e.g. "File", "Recent", "User Files", which would result in the + * File menu having a submenu called "Recent" which would have a + * submenu called "User Files". + * @return the last Menu object specified by the path + */ + private Menu createMenuPath(String... path) { + Menu m = menu; + + for (String p : path) { + Menu sub = m.getChildMenu(p); + + if (sub == null) { + sub = new Menu(p); + m.addChildMenu(sub); + } + m = sub; + } + + return m; + } + + @Override + public Element getSubPartElement(String subPart) { + if (testedWidget instanceof SubPartAware) { + return ((SubPartAware) testedWidget).getSubPartElement(subPart); + } + return null; + } + + @Override + public String getSubPartName(Element subElement) { + if (testedWidget instanceof SubPartAware) { + return ((SubPartAware) testedWidget).getSubPartName(subElement); + } + return null; + } + + /** + * Gets the tested widget. + * + * @return tested widget + */ + public T getTestedWidget() { + return testedWidget; + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java new file mode 100644 index 0000000000..63faf1d651 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/RowAwareRendererConnector.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.client.grid; + +import java.util.Arrays; +import java.util.Collection; + +import com.google.gwt.dom.client.BrowserEvents; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.NativeEvent; +import com.google.gwt.user.client.DOM; +import com.vaadin.client.connectors.AbstractRendererConnector; +import com.vaadin.client.renderers.ComplexRenderer; +import com.vaadin.client.renderers.Renderer; +import com.vaadin.client.widget.grid.CellReference; +import com.vaadin.client.widget.grid.RendererCellReference; +import com.vaadin.shared.communication.ServerRpc; +import com.vaadin.shared.ui.Connect; + +import elemental.json.JsonObject; + +@Connect(com.vaadin.tests.components.grid.RowAwareRenderer.class) +public class RowAwareRendererConnector extends AbstractRendererConnector<Void> { + public interface RowAwareRendererRpc extends ServerRpc { + void clicky(String key); + } + + public class RowAwareRenderer extends ComplexRenderer<Void> { + + @Override + public Collection<String> getConsumedEvents() { + return Arrays.asList(BrowserEvents.CLICK); + } + + @Override + public void init(RendererCellReference cell) { + DivElement div = DivElement.as(DOM.createDiv()); + div.setAttribute("style", + "border: 1px solid red; background: pink;"); + div.setInnerText("Click me!"); + cell.getElement().appendChild(div); + } + + @Override + public void render(RendererCellReference cell, Void data) { + // NOOP + } + + @Override + public boolean onBrowserEvent(CellReference<?> cell, NativeEvent event) { + String key = getRowKey((JsonObject) cell.getRow()); + getRpcProxy(RowAwareRendererRpc.class).clicky(key); + cell.getElement().setInnerText( + "row: " + cell.getRowIndex() + ", key: " + key); + return true; + } + } + + @Override + protected Renderer<Void> createRenderer() { + // cannot use the default createRenderer as RowAwareRenderer needs a + // reference to its connector - it has no "real" no-argument constructor + return new RowAwareRenderer(); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java b/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java new file mode 100644 index 0000000000..1bdbba2c36 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java @@ -0,0 +1,144 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.rebind; + +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +import com.google.gwt.core.ext.Generator; +import com.google.gwt.core.ext.GeneratorContext; +import com.google.gwt.core.ext.TreeLogger; +import com.google.gwt.core.ext.UnableToCompleteException; +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.core.ext.typeinfo.TypeOracle; +import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; +import com.google.gwt.user.rebind.SourceWriter; +import com.vaadin.client.metadata.Invoker; +import com.vaadin.tests.widgetset.client.TestWidgetConnector; +import com.vaadin.tests.widgetset.client.TestWidgetConnector.TestWidgetRegistry; + +public class TestWidgetRegistryGenerator extends Generator { + + @Override + public String generate(TreeLogger logger, GeneratorContext context, + String typeName) throws UnableToCompleteException { + + try { + TypeOracle typeOracle = context.getTypeOracle(); + + // get classType and save instance variables + JClassType classType = typeOracle.getType(typeName); + String packageName = classType.getPackage().getName(); + String className = classType.getSimpleSourceName() + "Impl"; + + // Generate class source code + generateClass(packageName, className, logger, context); + return packageName + "." + className; + } catch (Exception e) { + logger.log(TreeLogger.ERROR, + "Accept criterion factory creation failed", e); + throw new UnableToCompleteException(); + } + // return the fully qualifed name of the class generated + } + + private void generateClass(String packageName, String className, + TreeLogger logger, GeneratorContext context) { + PrintWriter printWriter = context.tryCreate(logger, packageName, + className); + // print writer if null, source code has ALREADY been generated + if (printWriter == null) { + return; + } + + // init composer, set class properties, create source writer + ClassSourceFileComposerFactory composer = null; + composer = new ClassSourceFileComposerFactory(packageName, className); + + composer.setSuperclass(TestWidgetRegistry.class.getCanonicalName()); + + List<JClassType> testWidgets = findTestWidgets(logger, + context.getTypeOracle()); + + SourceWriter w = composer.createSourceWriter(context, printWriter); + + w.println("public %s() {", className); + w.indent(); + + w.println("super();"); + w.println(); + + for (JClassType testWidgetType : testWidgets) { + w.println("register(\"%s\", new %s() {", + escape(testWidgetType.getQualifiedSourceName()), + Invoker.class.getCanonicalName()); + w.indent(); + + w.println("public Object invoke(Object target, Object... params) {"); + w.indent(); + + w.println("return new %s();", + testWidgetType.getQualifiedSourceName()); + + w.outdent(); + w.println("}"); + + w.outdent(); + w.println("});"); + w.println(); + } + + // Close constructor + w.outdent(); + w.println("}"); + + // Close class body + w.outdent(); + w.println("}"); + + // commit generated class + context.commit(logger, printWriter); + } + + private List<JClassType> findTestWidgets(TreeLogger logger, + TypeOracle typeOracle) { + List<JClassType> testWidgetTypes = new ArrayList<JClassType>(); + + JClassType[] widgetTypes = typeOracle.findType(Widget.class.getName()) + .getSubtypes(); + for (JClassType widgetType : widgetTypes) { + if (isTestWidget(widgetType)) { + testWidgetTypes.add(widgetType); + } + } + + return testWidgetTypes; + } + + private boolean isTestWidget(JClassType widgetType) { + if (widgetType.isAbstract()) { + return false; + } else if (!widgetType.getPackage().getName() + .startsWith(TestWidgetConnector.class.getPackage().getName())) { + return false; + } + + return true; + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java b/uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java new file mode 100644 index 0000000000..4b1aea67ea --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/LayoutDetector.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server; + +import com.vaadin.tests.widgetset.client.NoLayoutRpc; +import com.vaadin.ui.AbstractComponent; + +public class LayoutDetector extends AbstractComponent { + + public void doNoLayoutRpc() { + getRpcProxy(NoLayoutRpc.class).doRpc(); + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/TestWidgetComponent.java b/uitest/src/com/vaadin/tests/widgetset/server/TestWidgetComponent.java new file mode 100644 index 0000000000..1750e99727 --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/TestWidgetComponent.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server; + +import com.google.gwt.user.client.ui.Widget; +import com.vaadin.annotations.Widgetset; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.TestWidgetConnector; +import com.vaadin.tests.widgetset.client.TestWidgetConnector.TestWidgetState; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.UI; + +/** + * Testing component that shows any widget class inside the + * com.vaadin.tests.widgetset.client package. + */ +public class TestWidgetComponent extends AbstractComponent { + private static final String targetPackage = TestWidgetConnector.class + .getPackage().getName(); + + public TestWidgetComponent(Class<? extends Widget> widgetClass) { + String className = widgetClass.getCanonicalName(); + if (!className.startsWith(targetPackage)) { + throw new IllegalArgumentException( + "Widget class must be inside the " + targetPackage + + " package"); + } + + getState().widgetClass = className; + setSizeFull(); + } + + @Override + public void attach() { + super.attach(); + + Class<? extends UI> uiClass = getUI().getClass(); + + Widgetset widgetset = uiClass.getAnnotation(Widgetset.class); + if (widgetset == null + || !widgetset.value().equals(TestingWidgetSet.NAME)) { + throw new IllegalStateException("You must add @" + + Widgetset.class.getSimpleName() + "(" + + TestingWidgetSet.class.getSimpleName() + ".NAME) to " + + uiClass.getSimpleName()); + } + } + + @Override + protected TestWidgetState getState() { + return (TestWidgetState) super.getState(); + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/server/grid/GridClientColumnRenderers.java b/uitest/src/com/vaadin/tests/widgetset/server/grid/GridClientColumnRenderers.java new file mode 100644 index 0000000000..ce260f108d --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/server/grid/GridClientColumnRenderers.java @@ -0,0 +1,158 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.tests.widgetset.server.grid; + +import java.util.Arrays; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererConnector.Renderers; +import com.vaadin.tests.widgetset.client.grid.GridClientColumnRendererRpc; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.AbstractSelect.ItemCaptionMode; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.NativeButton; +import com.vaadin.ui.NativeSelect; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; + +@Widgetset(TestingWidgetSet.NAME) +public class GridClientColumnRenderers extends UI { + + /** + * Controls the grid on the client side + */ + public static class GridController extends AbstractComponent { + + private GridClientColumnRendererRpc rpc() { + return getRpcProxy(GridClientColumnRendererRpc.class); + } + + /** + * Adds a new column with a renderer to the grid. + */ + public void addColumn(Renderers renderer) { + rpc().addColumn(renderer); + } + + /** + * Tests detaching and attaching grid + */ + public void detachAttach() { + rpc().detachAttach(); + } + + /** + * @since + */ + public void triggerClientSorting() { + rpc().triggerClientSorting(); + } + + /** + * @since + */ + public void triggerClientSortingTest() { + rpc().triggerClientSortingTest(); + } + + /** + * @since + */ + public void shuffle() { + rpc().shuffle(); + } + } + + @Override + protected void init(VaadinRequest request) { + final GridController controller = new GridController(); + final CssLayout controls = new CssLayout(); + final VerticalLayout content = new VerticalLayout(); + + content.addComponent(controller); + content.addComponent(controls); + setContent(content); + + final NativeSelect select = new NativeSelect( + "Add Column with Renderer", Arrays.asList(Renderers.values())); + select.setItemCaptionMode(ItemCaptionMode.EXPLICIT); + for (Renderers renderer : Renderers.values()) { + select.setItemCaption(renderer, renderer.toString()); + } + select.setValue(Renderers.TEXT_RENDERER); + select.setNullSelectionAllowed(false); + controls.addComponent(select); + + NativeButton addColumnBtn = new NativeButton("Add"); + addColumnBtn.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + Renderers renderer = (Renderers) select.getValue(); + controller.addColumn(renderer); + } + }); + controls.addComponent(addColumnBtn); + + NativeButton detachAttachBtn = new NativeButton("DetachAttach"); + detachAttachBtn.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + controller.detachAttach(); + } + }); + controls.addComponent(detachAttachBtn); + + NativeButton shuffleButton = new NativeButton("Shuffle"); + shuffleButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + controller.shuffle(); + } + }); + controls.addComponent(shuffleButton); + + NativeButton sortButton = new NativeButton("Trigger sorting event"); + sortButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + controller.triggerClientSorting(); + } + }); + controls.addComponent(sortButton); + + NativeButton testSortingButton = new NativeButton("Test sorting"); + testSortingButton.addClickListener(new ClickListener() { + @Override + public void buttonClick(ClickEvent event) { + controller.triggerClientSortingTest(); + } + }); + controls.addComponent(testSortingButton); + + Label console = new Label(); + console.setContentMode(ContentMode.HTML); + console.setId("testDebugConsole"); + content.addComponent(console); + } +} |