From 702f00f86534ec35cecd9f28bdce3d262d95e818 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Mon, 11 Aug 2014 22:27:35 +0300 Subject: Made Valo test UI deterministic and added TB test Change-Id: I342fad836ad0d4014748a06c8ccfed53a99e6ece --- .../src/com/vaadin/tests/tb3/AbstractTB3Test.java | 73 +++++++ .../com/vaadin/tests/themes/valo/CalendarTest.java | 55 +---- .../com/vaadin/tests/themes/valo/CommonParts.java | 8 +- .../com/vaadin/tests/themes/valo/DateFields.java | 50 +++-- uitest/src/com/vaadin/tests/themes/valo/Forms.java | 2 +- .../src/com/vaadin/tests/themes/valo/Sliders.java | 26 ++- .../com/vaadin/tests/themes/valo/ValoThemeUI.java | 14 +- .../vaadin/tests/themes/valo/ValoThemeUITest.java | 239 +++++++++++++++++++++ 8 files changed, 389 insertions(+), 78 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java (limited to 'uitest/src/com') diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index 6c37e7b950..7e22537032 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -18,14 +18,25 @@ package com.vaadin.tests.tb3; import static com.vaadin.tests.tb3.TB3Runner.localWebDriverIsUsed; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.lang.reflect.Field; import java.net.URL; import java.util.Collections; import java.util.List; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpHost; +import org.apache.http.HttpResponse; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicHttpEntityEnclosingRequest; +import org.json.JSONException; +import org.json.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.runner.RunWith; @@ -42,6 +53,7 @@ import org.openqa.selenium.interactions.internal.Coordinates; import org.openqa.selenium.internal.Locatable; import org.openqa.selenium.remote.BrowserType; import org.openqa.selenium.remote.DesiredCapabilities; +import org.openqa.selenium.remote.HttpCommandExecutor; import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedConditions; @@ -51,6 +63,7 @@ import com.thoughtworks.selenium.webdriven.WebDriverBackedSelenium; import com.vaadin.server.LegacyApplication; import com.vaadin.server.UIProvider; import com.vaadin.testbench.TestBench; +import com.vaadin.testbench.TestBenchDriverProxy; import com.vaadin.testbench.TestBenchElement; import com.vaadin.testbench.TestBenchTestCase; import com.vaadin.tests.components.AbstractTestUIWithLog; @@ -1166,4 +1179,64 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { return true; } + // FIXME: Remove this once TB4 getRemoteControlName works properly + private RemoteWebDriver getRemoteDriver() { + WebDriver d = getDriver(); + if (d instanceof TestBenchDriverProxy) { + try { + Field f = TestBenchDriverProxy.class + .getDeclaredField("actualDriver"); + f.setAccessible(true); + return (RemoteWebDriver) f.get(d); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (d instanceof RemoteWebDriver) { + return (RemoteWebDriver) d; + } + + return null; + + } + + // FIXME: Remove this once TB4 getRemoteControlName works properly + protected String getRemoteControlName() { + try { + RemoteWebDriver d = getRemoteDriver(); + if (d == null) { + return null; + } + HttpCommandExecutor ce = (HttpCommandExecutor) d + .getCommandExecutor(); + String hostName = ce.getAddressOfRemoteServer().getHost(); + int port = ce.getAddressOfRemoteServer().getPort(); + HttpHost host = new HttpHost(hostName, port); + DefaultHttpClient client = new DefaultHttpClient(); + URL sessionURL = new URL("http://" + hostName + ":" + port + + "/grid/api/testsession?session=" + d.getSessionId()); + BasicHttpEntityEnclosingRequest r = new BasicHttpEntityEnclosingRequest( + "POST", sessionURL.toExternalForm()); + HttpResponse response = client.execute(host, r); + JSONObject object = extractObject(response); + URL myURL = new URL(object.getString("proxyId")); + if ((myURL.getHost() != null) && (myURL.getPort() != -1)) { + return myURL.getHost(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private static JSONObject extractObject(HttpResponse resp) + throws IOException, JSONException { + InputStream contents = resp.getEntity().getContent(); + StringWriter writer = new StringWriter(); + IOUtils.copy(contents, writer, "UTF8"); + JSONObject objToReturn = new JSONObject(writer.toString()); + return objToReturn; + } + } diff --git a/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java b/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java index 17dfd6cb67..280ddf98b7 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CalendarTest.java @@ -4,7 +4,6 @@ import java.text.DateFormatSymbols; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; -import java.util.Map; import java.util.TimeZone; import com.vaadin.annotations.Theme; @@ -51,6 +50,7 @@ import com.vaadin.ui.components.calendar.event.BasicEventProvider; import com.vaadin.ui.components.calendar.event.CalendarEvent; import com.vaadin.ui.components.calendar.handler.BasicDateClickHandler; import com.vaadin.ui.components.calendar.handler.BasicWeekClickHandler; +import com.vaadin.ui.themes.ValoTheme; /** Calendar component test application */ @Theme("valo-test") @@ -108,7 +108,7 @@ public class CalendarTest extends GridLayout implements View { private Button applyEventButton; - private Mode viewMode = Mode.MONTH; + private Mode viewMode = Mode.WEEK; private BasicEventProvider dataSource; @@ -152,52 +152,11 @@ public class CalendarTest extends GridLayout implements View { setSpacing(true); // handleURLParams(request.getParameterMap()); + testBench = ValoThemeUI.isTestMode(); initContent(); } - private void handleURLParams(Map parameters) { - testBench = parameters.containsKey("testBench") - || parameters.containsKey("?testBench"); - - if (parameters.containsKey("width")) { - calendarWidth = parameters.get("width")[0]; - } - - if (parameters.containsKey("height")) { - calendarHeight = parameters.get("height")[0]; - } - - if (parameters.containsKey("firstDay")) { - firstDay = Integer.parseInt(parameters.get("firstDay")[0]); - } - - if (parameters.containsKey("lastDay")) { - lastDay = Integer.parseInt(parameters.get("lastDay")[0]); - } - - if (parameters.containsKey("firstHour")) { - firstHour = Integer.parseInt(parameters.get("firstHour")[0]); - } - - if (parameters.containsKey("lastHour")) { - lastHour = Integer.parseInt(parameters.get("lastHour")[0]); - } - - if (parameters.containsKey("locale")) { - String localeArray[] = parameters.get("locale")[0].split("_"); - defaultLocale = new Locale(localeArray[0], localeArray[1]); - setLocale(defaultLocale); - } - - if (parameters.containsKey(("secondsResolution"))) { - useSecondResolution = true; - } - - showWeeklyView = parameters.containsKey("weekly"); - - } - public void initContent() { // Set default Locale for this application if (testBench) { @@ -365,6 +324,9 @@ public class CalendarTest extends GridLayout implements View { Alignment.MIDDLE_LEFT); controlPanel.setComponentAlignment(addNewEvent, Alignment.MIDDLE_LEFT); + Label viewCaption = new Label("Calendar"); + viewCaption.setStyleName(ValoTheme.LABEL_H1); + addComponent(viewCaption); addComponent(controlPanel); addComponent(hl); addComponent(calendarComponent); @@ -645,6 +607,11 @@ public class CalendarTest extends GridLayout implements View { calendar.setTime(today); calendarComponent.getInternalCalendar().setTime(today); + // Calendar getStartDate (and getEndDate) has some strange logic which + // returns Monday of the current internal time if no start date has been + // set + calendarComponent.setStartDate(calendarComponent.getStartDate()); + calendarComponent.setEndDate(calendarComponent.getEndDate()); int rollAmount = calendar.get(GregorianCalendar.DAY_OF_MONTH) - 1; calendar.add(GregorianCalendar.DAY_OF_MONTH, -rollAmount); currentMonthsFirstDate = calendar.getTime(); diff --git a/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java b/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java index cd378c3754..52cc43ac28 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java +++ b/uitest/src/com/vaadin/tests/themes/valo/CommonParts.java @@ -131,9 +131,11 @@ public class CommonParts extends VerticalLayout implements View { spinnerDesc.setCaption("Spinner"); content.addComponent(spinnerDesc); - Label spinner = new Label(); - spinner.addStyleName("spinner"); - content.addComponent(spinner); + if (!ValoThemeUI.isTestMode()) { + Label spinner = new Label(); + spinner.addStyleName("spinner"); + content.addComponent(spinner); + } return p; } diff --git a/uitest/src/com/vaadin/tests/themes/valo/DateFields.java b/uitest/src/com/vaadin/tests/themes/valo/DateFields.java index ae520e07c2..41aa287f9f 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/DateFields.java +++ b/uitest/src/com/vaadin/tests/themes/valo/DateFields.java @@ -46,16 +46,16 @@ public class DateFields extends VerticalLayout implements View { addComponent(row); DateField date = new DateField("Default resolution"); - date.setValue(new Date()); + setDate(date); row.addComponent(date); date = new DateField("Error"); - date.setValue(new Date()); + setDate(date); date.setComponentError(new UserError("Fix it, now!")); row.addComponent(date); date = new DateField("Error, borderless"); - date.setValue(new Date()); + setDate(date); date.setComponentError(new UserError("Fix it, now!")); date.addStyleName("borderless"); row.addComponent(date); @@ -77,110 +77,120 @@ public class DateFields extends VerticalLayout implements View { group.addComponent(today); date = new DateField("Default resolution, explicit size"); - date.setValue(new Date()); + setDate(date); row.addComponent(date); date.setWidth("260px"); date.setHeight("60px"); date = new DateField("Second resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.SECOND); row.addComponent(date); date = new DateField("Minute resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.MINUTE); row.addComponent(date); date = new DateField("Hour resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.HOUR); row.addComponent(date); date = new DateField("Disabled"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.HOUR); date.setEnabled(false); row.addComponent(date); date = new DateField("Day resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); row.addComponent(date); date = new DateField("Month resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.MONTH); row.addComponent(date); date = new DateField("Year resolution"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.YEAR); row.addComponent(date); date = new DateField("Custom color"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("color1"); row.addComponent(date); date = new DateField("Custom color"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("color2"); row.addComponent(date); date = new DateField("Custom color"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("color3"); row.addComponent(date); date = new DateField("Small"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("small"); row.addComponent(date); date = new DateField("Large"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("large"); row.addComponent(date); date = new DateField("Borderless"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.addStyleName("borderless"); row.addComponent(date); date = new DateField("Week numbers"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.DAY); date.setLocale(new Locale("fi", "fi")); date.setShowISOWeekNumbers(true); row.addComponent(date); date = new DateField("US locale"); - date.setValue(new Date()); + setDate(date); date.setResolution(Resolution.SECOND); date.setLocale(new Locale("en", "US")); row.addComponent(date); date = new DateField("Custom format"); - date.setValue(new Date()); + setDate(date); date.setDateFormat("E dd/MM/yyyy"); row.addComponent(date); date = new InlineDateField("Date picker"); + setDate(date); row.addComponent(date); date = new InlineDateField("Date picker with week numbers"); + setDate(date); date.setLocale(new Locale("fi", "fi")); date.setShowISOWeekNumbers(true); row.addComponent(date); } + private void setDate(DateField date) { + if (ValoThemeUI.isTestMode()) { + date.setValue(new Date(2014 - 1900, 5, 7)); + } else { + date.setValue(new Date()); + } + } + @Override public void enter(ViewChangeEvent event) { // TODO Auto-generated method stub diff --git a/uitest/src/com/vaadin/tests/themes/valo/Forms.java b/uitest/src/com/vaadin/tests/themes/valo/Forms.java index 6f1b8bbf7a..c5b08902be 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Forms.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Forms.java @@ -47,7 +47,7 @@ public class Forms extends VerticalLayout implements View { setSpacing(true); setMargin(true); - Label title = new Label("Form"); + Label title = new Label("Forms"); title.addStyleName("h1"); addComponent(title); diff --git a/uitest/src/com/vaadin/tests/themes/valo/Sliders.java b/uitest/src/com/vaadin/tests/themes/valo/Sliders.java index 363c698c32..8ed846e39f 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/Sliders.java +++ b/uitest/src/com/vaadin/tests/themes/valo/Sliders.java @@ -158,11 +158,12 @@ public class Sliders extends VerticalLayout implements View { // pb2.setValue(0.6f); row.addComponent(pb2); - ProgressBar pb3 = new ProgressBar(); - pb3.setIndeterminate(true); - pb3.setCaption("Indeterminate"); - row.addComponent(pb3); - + if (!ValoThemeUI.isTestMode()) { + ProgressBar pb3 = new ProgressBar(); + pb3.setIndeterminate(true); + pb3.setCaption("Indeterminate"); + row.addComponent(pb3); + } } float progress = 0; @@ -196,14 +197,21 @@ public class Sliders extends VerticalLayout implements View { @Override public void enter(ViewChangeEvent event) { - getUI().setPollInterval(1000); - update.start(); + if (!ValoThemeUI.isTestMode()) { + getUI().setPollInterval(1000); + update.start(); + } else { + pb.setValue(0.3f); + pb2.setValue(0.6f); + } } @Override public void detach() { - getUI().setPollInterval(-1); - update.interrupt(); + if (!ValoThemeUI.isTestMode()) { + getUI().setPollInterval(-1); + update.interrupt(); + } super.detach(); } diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java index 5f286989a0..501b5f573b 100644 --- a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUI.java @@ -61,6 +61,8 @@ import com.vaadin.ui.themes.ValoTheme; @PreserveOnRefresh public class ValoThemeUI extends UI { + private boolean testMode = false; + private static LinkedHashMap themeVariants = new LinkedHashMap(); static { themeVariants.put("tests-valo", "Default"); @@ -77,11 +79,17 @@ public class ValoThemeUI extends UI { ComponentContainer viewDisplay = root.getContentContainer(); CssLayout menu = new CssLayout(); CssLayout menuItemsLayout = new CssLayout(); + { + menu.setId("testMenu"); + } private Navigator navigator; private LinkedHashMap menuItems = new LinkedHashMap(); @Override protected void init(VaadinRequest request) { + if (request.getParameter("test") != null) { + testMode = true; + } // Show .v-app-loading valo-menu-badge // try { // Thread.sleep(2000); @@ -159,6 +167,10 @@ public class ValoThemeUI extends UI { } + static boolean isTestMode() { + return ((ValoThemeUI) getCurrent()).testMode; + } + Component buildTestMenu() { CssLayout menu = new CssLayout(); menu.addStyleName("large-icons"); @@ -398,7 +410,7 @@ public class ValoThemeUI extends UI { // ((Hierarchical) container).setChildrenAllowed(id, false); ((Hierarchical) container).setParent(id, i); - for (int k = 1; k < 5; k++) { + for (int k = 1; k < 6; k++) { String id2 = id + " -> " + k; child = container.addItem(id2); child.getItemProperty(CAPTION_PROPERTY).setValue( diff --git a/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java new file mode 100644 index 0000000000..fdb2eabeee --- /dev/null +++ b/uitest/src/com/vaadin/tests/themes/valo/ValoThemeUITest.java @@ -0,0 +1,239 @@ +/* + * 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.themes.valo; + +import org.junit.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.WebElement; + +import com.vaadin.testbench.elements.ButtonElement; +import com.vaadin.testbench.elements.CssLayoutElement; +import com.vaadin.testbench.elements.LabelElement; +import com.vaadin.testbench.elements.TreeElement; +import com.vaadin.tests.tb3.MultiBrowserTest; + +public class ValoThemeUITest extends MultiBrowserTest { + + @Test + public void labels() throws Exception { + openTestURL("test"); + open("Labels"); + compareScreen("labels"); + } + + @Test + public void buttonsLinks() throws Exception { + openTestURL("test"); + open("Buttons & Links", "Buttons"); + compareScreen("buttonsLinks"); + } + + @Test + public void textFields() throws Exception { + openTestURL("test"); + open("Text Fields 123", + "Text Fields"); + compareScreen("textFields"); + } + + @Test + public void common() throws Exception { + openTestURL("test"); + open("Common UI Elements"); + compareScreen("common"); + } + + @Test + public void datefields() throws Exception { + openTestURL("test"); + open("Date Fields"); + // Note that this can look broken in IE9 because of some browser + // rendering issue... The problem seems to be in the customized + // horizontal layout in the test app + compareScreen("datefields"); + } + + @Test + public void comboboxes() throws Exception { + openTestURL("test"); + open("Combo Boxes"); + compareScreen("comboboxes"); + } + + @Test + public void selects() throws Exception { + openTestURL("test"); + open("Selects"); + compareScreen("selects"); + } + + @Test + public void checkboxes() throws Exception { + openTestURL("test"); + open("Check Boxes & Option Groups", "Check Boxes"); + compareScreen("checkboxes"); + } + + @Test + public void sliders() throws Exception { + openTestURL("test"); + open("Sliders & Progress Bars", "Sliders"); + compareScreen("sliders"); + } + + @Test + public void colorpickers() throws Exception { + openTestURL("test"); + open("Color Pickers"); + compareScreen("colorpickers"); + } + + @Test + public void menubars() throws Exception { + openTestURL("test"); + open("Menu Bars"); + compareScreen("menubars"); + } + + @Test + public void trees() throws Exception { + openTestURL("test"); + open("Trees"); + selectTreeNodeByCaption("Quid securi"); + compareScreen("trees"); + } + + private void selectTreeNodeByCaption(String string) { + WebElement e = $(TreeElement.class).first().findElement( + By.xpath("//div[@class='v-tree-node-caption']//span[text()='" + + string + "']")); + e.click(); + } + + @Test + public void tables() throws Exception { + openTestURL("test"); + open("Tables"); + compareScreen("tables"); + } + + @Test + public void dragging() throws Exception { + openTestURL("test"); + open("Drag and Drop", "Dragging Components"); + compareScreen("dragging"); + } + + @Test + public void panels() throws Exception { + openTestURL("test"); + open("Panels", "Panels & Layout panels"); + compareScreen("panels"); + } + + @Test + public void splitpanels() throws Exception { + openTestURL("test"); + open("Split Panels"); + compareScreen("splitpanels"); + } + + @Test + public void tabs() throws Exception { + openTestURL("test"); + open("Tabs 123", "Tabs"); + compareScreen("tabs"); + } + + @Test + public void accordions() throws Exception { + openTestURL("test"); + open("Accordions"); + compareScreen("accordions"); + } + + @Test + public void popupviews() throws Exception { + openTestURL("test"); + open("Popup Views"); + scrollTo(500, 0); + compareScreen("popupviews"); + } + + @Test + public void calendar() throws Exception { + openTestURL("test"); + scrollTo(500, 0); + open("Calendar"); + + compareScreen("calendar"); + } + + @Test + public void forms() throws Exception { + openTestURL("test"); + scrollTo(500, 0); + open("Forms"); + compareScreen("forms"); + } + + private void open(String link) { + open(link, link); + } + + private void open(String link, String caption) { + open(link, caption, 10); + } + + // FIXME: Remove this once click works properly on IE... + private void open(String link, String caption, int tries) { + if (tries <= 0) { + throw new RuntimeException( + "Tried many times but was not able to click the link..."); + } + + $(ButtonElement.class).caption(link).first().click(); + CssLayoutElement content = wrap(CssLayoutElement.class, + findElement(By.className("valo-content"))); + LabelElement captionElem = content.$(LabelElement.class).first(); + if (!captionElem.getText().equals(caption)) { + // IE ... why you fail clicks + System.err.println("Extra click needed on '" + link + + "' on remote " + getDesiredCapabilities() + " " + + getRemoteControlName()); + + open(link, caption, tries - 1); + } + } + + private void scrollTo(int top, int left) { + CssLayoutElement testMenu = $(CssLayoutElement.class).id("testMenu"); + + testBenchElement(testMenu).scroll(top); + testBenchElement(testMenu).scrollLeft(left); + } + + @Override + protected boolean requireWindowFocusForIE() { + return true; + } + + @Override + protected boolean usePersistentHoverForIE() { + return false; + } + +} -- cgit v1.2.3