@@ -344,7 +344,7 @@ public class DateTimeService { | |||
if (formatStr.contains("EEE")) { | |||
String dayName = getShortDay(date.getMonth()); | |||
String dayName = getShortDay(date.getDay()); | |||
if (dayName != null) { | |||
/* |
@@ -74,6 +74,15 @@ public class LayoutManager { | |||
this.connection = connection; | |||
} | |||
/** | |||
* Returns the application connection for this layout manager. | |||
* | |||
* @return connection | |||
*/ | |||
protected ApplicationConnection getConnection() { | |||
return connection; | |||
} | |||
/** | |||
* Gets the layout manager associated with the given | |||
* {@link ApplicationConnection}. |
@@ -21,6 +21,7 @@ import java.util.Map; | |||
import com.google.gwt.dom.client.Document; | |||
import com.google.gwt.dom.client.Element; | |||
import com.google.gwt.dom.client.Node; | |||
import com.google.gwt.user.client.ui.RootPanel; | |||
/** | |||
@@ -39,6 +40,12 @@ public class LayoutManagerIE8 extends LayoutManager { | |||
private Map<Element, MeasuredSize> measuredSizes = new HashMap<Element, MeasuredSize>(); | |||
// this method is needed to test for memory leaks (see | |||
// LayoutMemoryUsageIE8ExtensionConnector) but can be private | |||
private int getMeasuredSizesMapSize() { | |||
return measuredSizes.size(); | |||
} | |||
@Override | |||
protected void setMeasuredSize(Element element, MeasuredSize measuredSize) { | |||
if (measuredSize != null) { | |||
@@ -62,12 +69,16 @@ public class LayoutManagerIE8 extends LayoutManager { | |||
@Override | |||
protected void cleanMeasuredSizes() { | |||
Profiler.enter("LayoutManager.cleanMeasuredSizes"); | |||
Document document = RootPanel.get().getElement().getOwnerDocument(); | |||
// #12688: IE8 was leaking memory when adding&removing components. | |||
// Uses IE specific logic to figure if an element has been removed from | |||
// DOM or not. For removed elements the measured size is discarded. | |||
Node rootNode = Document.get().getBody(); | |||
Iterator<Element> i = measuredSizes.keySet().iterator(); | |||
while (i.hasNext()) { | |||
Element e = i.next(); | |||
if (e.getOwnerDocument() != document) { | |||
if (!rootNode.isOrHasChild(e)) { | |||
i.remove(); | |||
} | |||
} |
@@ -1189,6 +1189,7 @@ public class VCalendarPanel extends FocusableFlexTable implements | |||
} else if (keycode == getCloseKey()) { | |||
// TODO fire listener, on users responsibility?? | |||
onCancel(); | |||
return true; | |||
} | |||
return false; | |||
@@ -1240,6 +1241,7 @@ public class VCalendarPanel extends FocusableFlexTable implements | |||
return true; | |||
} else if (keycode == getCloseKey() || keycode == KeyCodes.KEY_TAB) { | |||
onCancel(); | |||
// TODO fire close event | |||
@@ -1062,9 +1062,7 @@ public class VTabsheet extends VTabsheetBase implements Focusable, | |||
*/ | |||
private void updateTabScroller() { | |||
if (!isDynamicWidth()) { | |||
ComponentConnector paintable = ConnectorMap.get(client) | |||
.getConnector(this); | |||
DOM.setStyleAttribute(tabs, "width", paintable.getState().width); | |||
DOM.setStyleAttribute(tabs, "width", "100%"); | |||
} | |||
// Make sure scrollerIndex is valid |
@@ -270,8 +270,7 @@ public abstract class AbstractOrderedLayoutConnector extends | |||
if (slot.hasCaption()) { | |||
CaptionPosition pos = slot.getCaptionPosition(); | |||
getLayoutManager().addElementResizeListener( | |||
slot.getCaptionElement(), slotCaptionResizeListener); | |||
slot.setCaptionResizeListener(slotCaptionResizeListener); | |||
if (child.isRelativeHeight() | |||
&& (pos == CaptionPosition.TOP || pos == CaptionPosition.BOTTOM)) { | |||
getWidget().updateCaptionOffset(slot.getCaptionElement()); |
@@ -227,6 +227,9 @@ public class FileUploadHandler implements RequestHandler { | |||
/* Same as in apache commons file upload library that was previously used. */ | |||
private static final int MAX_UPLOAD_BUFFER_SIZE = 4 * 1024; | |||
/* Minimum interval which will be used for streaming progress events. */ | |||
public static final int DEFAULT_STREAMING_PROGRESS_EVENT_INTERVAL_MS = 500; | |||
@Override | |||
public boolean handleRequest(VaadinSession session, VaadinRequest request, | |||
VaadinResponse response) throws IOException { | |||
@@ -550,26 +553,35 @@ public class FileUploadHandler implements RequestHandler { | |||
} | |||
final byte buffer[] = new byte[MAX_UPLOAD_BUFFER_SIZE]; | |||
long lastStreamingEvent = 0; | |||
int bytesReadToBuffer = 0; | |||
while ((bytesReadToBuffer = in.read(buffer)) > 0) { | |||
out.write(buffer, 0, bytesReadToBuffer); | |||
totalBytes += bytesReadToBuffer; | |||
do { | |||
bytesReadToBuffer = in.read(buffer); | |||
if (bytesReadToBuffer > 0) { | |||
out.write(buffer, 0, bytesReadToBuffer); | |||
totalBytes += bytesReadToBuffer; | |||
} | |||
if (listenProgress) { | |||
// update progress if listener set and contentLength | |||
// received | |||
session.lock(); | |||
try { | |||
StreamingProgressEventImpl progressEvent = new StreamingProgressEventImpl( | |||
filename, type, contentLength, totalBytes); | |||
streamVariable.onProgress(progressEvent); | |||
} finally { | |||
session.unlock(); | |||
long now = System.currentTimeMillis(); | |||
// to avoid excessive session locking and event storms, | |||
// events are sent in intervals, or at the end of the file. | |||
if (lastStreamingEvent + getProgressEventInterval() <= now | |||
|| bytesReadToBuffer <= 0) { | |||
lastStreamingEvent = now; | |||
session.lock(); | |||
try { | |||
StreamingProgressEventImpl progressEvent = new StreamingProgressEventImpl( | |||
filename, type, contentLength, totalBytes); | |||
streamVariable.onProgress(progressEvent); | |||
} finally { | |||
session.unlock(); | |||
} | |||
} | |||
} | |||
if (streamVariable.isInterrupted()) { | |||
throw new UploadInterruptedException(); | |||
} | |||
} | |||
} while (bytesReadToBuffer > 0); | |||
// upload successful | |||
out.close(); | |||
@@ -612,6 +624,17 @@ public class FileUploadHandler implements RequestHandler { | |||
return startedEvent.isDisposed(); | |||
} | |||
/** | |||
* To prevent event storming, streaming progress events are sent in this | |||
* interval rather than every time the buffer is filled. This fixes #13155. | |||
* To adjust this value override the method, and register your own handler | |||
* in VaadinService.createRequestHandlers(). The default is 500ms, and | |||
* setting it to 0 effectively restores the old behavior. | |||
*/ | |||
protected int getProgressEventInterval() { | |||
return DEFAULT_STREAMING_PROGRESS_EVENT_INTERVAL_MS; | |||
} | |||
static void tryToCloseStream(OutputStream out) { | |||
try { | |||
// try to close output stream (e.g. file handle) |
@@ -613,7 +613,18 @@ public abstract class UI extends AbstractSingleComponentContainer implements | |||
*/ | |||
public void doInit(VaadinRequest request, int uiId, String embedId) { | |||
if (this.uiId != -1) { | |||
throw new IllegalStateException("UI id has already been defined"); | |||
String message = "This UI instance is already initialized (as UI id " | |||
+ this.uiId | |||
+ ") and can therefore not be initialized again (as UI id " | |||
+ uiId + "). "; | |||
if (getSession() != null | |||
&& !getSession().equals(VaadinSession.getCurrent())) { | |||
message += "Furthermore, it is already attached to another VaadinSession. "; | |||
} | |||
message += "Please make sure you are not accidentally reusing an old UI instance."; | |||
throw new IllegalStateException(message); | |||
} | |||
this.uiId = uiId; | |||
this.embedId = embedId; |
@@ -0,0 +1,59 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.datefield; | |||
import java.util.Calendar; | |||
import java.util.Locale; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.shared.ui.datefield.Resolution; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.DateField; | |||
import com.vaadin.ui.VerticalLayout; | |||
public class CustomDateFormatEEE extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Calendar cal = Calendar.getInstance(); | |||
cal.set(2014, 2, 14); // Friday | |||
DateField df = new DateField("Should display 14/03/2014 Fri"); | |||
df.setResolution(Resolution.DAY); | |||
df.setLocale(new Locale("en", "US")); | |||
String pattern = "dd/MM/yyyy EEE"; | |||
df.setDateFormat(pattern); | |||
df.setValue(cal.getTime()); | |||
df.setWidth("200px"); | |||
VerticalLayout layout = new VerticalLayout(); | |||
layout.addComponent(df); | |||
layout.setMargin(true); | |||
setContent(layout); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Verifies that \"EEE\" works as a part of custom date pattern"; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 13443; | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.datefield; | |||
import static org.junit.Assert.assertEquals; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class CustomDateFormatEEETest extends MultiBrowserTest { | |||
@Test | |||
public void verifyDatePattern() { | |||
openTestURL(); | |||
String dateValue = driver.findElement( | |||
By.className("v-datefield-textfield")).getAttribute("value"); | |||
assertEquals("14/03/2014 Fri", dateValue); | |||
} | |||
} |
@@ -0,0 +1,57 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.datefield; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.shared.ui.datefield.Resolution; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.DateField; | |||
import com.vaadin.ui.VerticalLayout; | |||
public class PopupClosingWithEsc extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
DateField df1 = new DateField("Day"); | |||
df1.setId("day"); | |||
df1.setResolution(Resolution.DAY); | |||
DateField df2 = new DateField("Month"); | |||
df2.setId("month"); | |||
df2.setResolution(Resolution.MONTH); | |||
DateField df3 = new DateField("Year"); | |||
df3.setId("year"); | |||
df3.setResolution(Resolution.YEAR); | |||
VerticalLayout layout = new VerticalLayout(); | |||
layout.setMargin(true); | |||
layout.setSpacing(true); | |||
layout.addComponents(df1, df2, df3); | |||
setContent(layout); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Testing that the DateField popup can be closed with ESC key."; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 12317; | |||
} | |||
} |
@@ -0,0 +1,67 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.datefield; | |||
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.WebElement; | |||
import org.openqa.selenium.interactions.Actions; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class PopupClosingWithEscTest extends MultiBrowserTest { | |||
@Test | |||
public void testPopupClosingDayResolution() { | |||
testPopupClosing("day"); | |||
} | |||
@Test | |||
public void testPopupClosingMonthResolution() { | |||
testPopupClosing("month"); | |||
} | |||
@Test | |||
public void testPopupClosingYearResolution() { | |||
testPopupClosing("year"); | |||
} | |||
private void testPopupClosing(String dateFieldId) { | |||
openTestURL(); | |||
driver.findElement( | |||
vaadinLocator("PID_S" + dateFieldId + "#popupButton")).click(); | |||
assertTrue(isPopupVisible()); | |||
sendEsc(); | |||
assertFalse(isPopupVisible()); | |||
} | |||
private boolean isPopupVisible() { | |||
return !(driver.findElements(By.cssSelector(".v-datefield-popup")) | |||
.isEmpty()); | |||
} | |||
private void sendEsc() { | |||
WebElement elem = driver.findElement(By | |||
.cssSelector(".v-datefield-calendarpanel")); | |||
new Actions(driver).sendKeys(elem, Keys.ESCAPE).perform(); | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
package com.vaadin.tests.components.orderedlayout; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.ComponentContainer; | |||
import com.vaadin.ui.CssLayout; | |||
import com.vaadin.ui.Label; | |||
import com.vaadin.ui.Panel; | |||
import com.vaadin.ui.TextField; | |||
import com.vaadin.ui.UI; | |||
import com.vaadin.ui.VerticalLayout; | |||
/** | |||
* HorizontalLayout and VerticalLayout should not leak caption elements via | |||
* listeners when removing components from a layout. | |||
* | |||
* @since 7.1.13 | |||
* @author Vaadin Ltd | |||
*/ | |||
public class CaptionLeak extends UI { | |||
public static final String USAGE = "Open this UI with ?debug and count" | |||
+ " measured non-connector elements after setting leaky and non leaky" | |||
+ " content."; | |||
@Override | |||
public void init(VaadinRequest req) { | |||
final VerticalLayout root = new VerticalLayout(); | |||
setContent(root); | |||
Label usage = new Label(USAGE); | |||
Panel parent = new Panel(); | |||
Button setLeakyContent = makeButton("Set leaky content", parent, | |||
VerticalLayout.class); | |||
Button setNonLeakyContent = makeButton("Set non leaky content", parent, | |||
CssLayout.class); | |||
root.addComponents(usage, setLeakyContent, setNonLeakyContent, parent); | |||
} | |||
private Button makeButton(String caption, final Panel parent, | |||
final Class<? extends ComponentContainer> targetClass) { | |||
Button btn = new Button(caption); | |||
btn.setId(caption); | |||
btn.addClickListener(new Button.ClickListener() { | |||
@Override | |||
public void buttonClick(Button.ClickEvent event) { | |||
try { | |||
ComponentContainer target = targetClass.newInstance(); | |||
for (int i = 0; i < 61; i++) { | |||
target.addComponent(new TextField("Test")); | |||
} | |||
parent.setContent(target); | |||
} catch (InstantiationException e) { | |||
throw new RuntimeException(e); | |||
} catch (IllegalAccessException e) { | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
}); | |||
return btn; | |||
} | |||
} |
@@ -0,0 +1,68 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.orderedlayout; | |||
import org.junit.Test; | |||
import org.openqa.selenium.By; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class CaptionLeakTest extends MultiBrowserTest { | |||
@Test | |||
public void testCaptionLeak() throws Exception { | |||
setDebug(true); | |||
openTestURL(); | |||
// this should be present | |||
// 3 general non-connector elements, none accumulated on click | |||
getDriver() | |||
.findElement( | |||
By.xpath("//span[text() = 'Measured 3 non connector elements']")); | |||
getDriver().findElement(By.xpath("//button[@title = 'Clear log']")) | |||
.click(); | |||
getDriver().findElement(By.id("Set leaky content")).click(); | |||
getDriver() | |||
.findElement( | |||
By.xpath("//span[text() = 'Measured 3 non connector elements']")); | |||
// nothing accumulates over clicks | |||
getDriver().findElement(By.xpath("//button[@title = 'Clear log']")) | |||
.click(); | |||
getDriver().findElement(By.id("Set leaky content")).click(); | |||
getDriver() | |||
.findElement( | |||
By.xpath("//span[text() = 'Measured 3 non connector elements']")); | |||
} | |||
@Test | |||
public void testNoCaptionLeak() throws Exception { | |||
setDebug(true); | |||
openTestURL(); | |||
getDriver().findElement(By.xpath("//button[@title = 'Clear log']")) | |||
.click(); | |||
getDriver().findElement(By.id("Set non leaky content")).click(); | |||
// this should be present | |||
// 3 general non-connector elements, none accumulated on click | |||
getDriver() | |||
.findElement( | |||
By.xpath("//span[text() = 'Measured 3 non connector elements']")); | |||
} | |||
} |
@@ -0,0 +1,105 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.tabsheet; | |||
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.Component; | |||
import com.vaadin.ui.TabSheet; | |||
import com.vaadin.ui.VerticalLayout; | |||
/** | |||
* Tests the width of the tab bar, especially when using relative width for the | |||
* {@link TabSheet}. | |||
* | |||
* Created for ticket <a href="http://dev.vaadin.com/ticket/12805">#12805</a>. | |||
*/ | |||
public class TabBarWidth extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
final VerticalLayout layout = new VerticalLayout(); | |||
layout.setMargin(true); | |||
layout.setSpacing(true); | |||
layout.setWidth("500px"); | |||
setContent(layout); | |||
// Add a Button to toggle between the widths and undefined. | |||
Button toggle = new Button("Toggle widths", new Button.ClickListener() { | |||
private boolean removeWidths = true; | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
restoreOrRemoveWidths(layout, removeWidths); | |||
removeWidths = !removeWidths; | |||
} | |||
}); | |||
toggle.setId("toggleWidths"); | |||
layout.addComponent(toggle); | |||
// Add TabSheets with different widths specified. | |||
layout.addComponent(newTabSheet(null)); | |||
layout.addComponent(newTabSheet("100%")); | |||
layout.addComponent(newTabSheet("75%")); | |||
layout.addComponent(newTabSheet("50%")); | |||
layout.addComponent(newTabSheet("150px")); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Tests the width of the tab bar."; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 12805; | |||
} | |||
private void restoreOrRemoveWidths(VerticalLayout layout, | |||
boolean removeWidths) { | |||
for (Component component : layout) { | |||
if (component instanceof TabSheet) { | |||
if (removeWidths) { | |||
component.setWidth(null); | |||
component.setCaption("Width: undefined"); | |||
} else { | |||
String originalWidth = (String) ((TabSheet) component) | |||
.getData(); | |||
component.setWidth(originalWidth); | |||
component.setCaption("Width: " | |||
+ (originalWidth == null ? "undefined" | |||
: originalWidth)); | |||
} | |||
} | |||
} | |||
} | |||
private TabSheet newTabSheet(String width) { | |||
TabSheet tabSheet = new TabSheet(); | |||
tabSheet.setCaption("Width: " + (width == null ? "undefined" : width)); | |||
tabSheet.setWidth(width); | |||
tabSheet.setData(width); | |||
// Add dummy components to fill the TabSheet. | |||
for (int i = 1; i <= 10; i++) { | |||
tabSheet.addComponent(new Button(i + ". tab")); | |||
} | |||
return tabSheet; | |||
} | |||
} |
@@ -0,0 +1,41 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.components.tabsheet; | |||
import org.junit.Test; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class TabBarWidthTest extends MultiBrowserTest { | |||
@Test | |||
public void testWidths() throws Exception { | |||
openTestURL(); | |||
// Initial rendering. | |||
compareScreen("tab-bar-width-init"); | |||
// Remove all widths. | |||
vaadinElementById("toggleWidths").click(); | |||
compareScreen("tab-bar-width-undefined"); | |||
// Restore all widths. This should restore the rendering to the same | |||
// point as the initial rendering. | |||
vaadinElementById("toggleWidths").click(); | |||
compareScreen("tab-bar-width-restored"); | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.extensions; | |||
import com.vaadin.server.AbstractExtension; | |||
import com.vaadin.ui.UI; | |||
/** | |||
* Test extension for finding out the size of the measuredSizes map of | |||
* LayoutManagerIE8. | |||
* | |||
* This UI extension uses JSNI to register a JavaScript method | |||
* window.vaadin.getMeasuredSizesCount() that can be used to query the size of | |||
* the internal map of the layout manager. It should only be used on IE8. | |||
* | |||
* @since 7.1.13 | |||
* @author Vaadin Ltd | |||
*/ | |||
public class LayoutMemoryUsageIE8Extension extends AbstractExtension { | |||
public void extend(UI target) { | |||
super.extend(target); | |||
} | |||
} |
@@ -15,15 +15,8 @@ | |||
*/ | |||
package com.vaadin.tests.integration; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Parameterized.Parameters; | |||
import org.openqa.selenium.remote.DesiredCapabilities; | |||
import com.vaadin.tests.tb3.MultiBrowserTest.Browser; | |||
import com.vaadin.tests.tb3.PrivateTB3Configuration; | |||
import com.vaadin.tests.tb3.TestNameSuffix; | |||
/** | |||
* Base class for integration tests. Integration tests use the | |||
@@ -32,7 +25,7 @@ import com.vaadin.tests.tb3.PrivateTB3Configuration; | |||
* | |||
* @author Vaadin Ltd | |||
*/ | |||
@RunWith(IntegrationTestRunner.class) | |||
@TestNameSuffix(property = "server-name") | |||
public abstract class AbstractIntegrationTest extends PrivateTB3Configuration { | |||
@Override | |||
protected String getBaseURL() { | |||
@@ -41,13 +34,7 @@ public abstract class AbstractIntegrationTest extends PrivateTB3Configuration { | |||
throw new RuntimeException( | |||
"Deployment url must be given as deployment.url"); | |||
} | |||
return deploymentUrl; | |||
} | |||
@Parameters | |||
public static Collection<DesiredCapabilities> getBrowsersForTest() { | |||
return Collections.singleton(Browser.FIREFOX.getDesiredCapabilities()); | |||
} | |||
} |
@@ -1,54 +0,0 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.integration; | |||
import org.junit.runners.model.FrameworkMethod; | |||
import org.junit.runners.model.InitializationError; | |||
import com.vaadin.tests.tb3.TB3Runner; | |||
/** | |||
* JUnit runner for integration tests. Replaces the actual method name with the | |||
* server-name property when generating the test name. | |||
* | |||
* @author Vaadin Ltd | |||
*/ | |||
public class IntegrationTestRunner extends TB3Runner { | |||
private Class<?> testClass; | |||
public IntegrationTestRunner(Class<?> klass) throws InitializationError { | |||
super(klass); | |||
testClass = klass; | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see | |||
* org.junit.runners.BlockJUnit4ClassRunner#testName(org.junit.runners.model | |||
* .FrameworkMethod) | |||
*/ | |||
@Override | |||
protected String testName(FrameworkMethod method) { | |||
if (AbstractIntegrationTest.class.isAssignableFrom(testClass)) { | |||
return System.getProperty("server-name"); | |||
} else { | |||
return super.testName(method); | |||
} | |||
} | |||
} |
@@ -50,6 +50,9 @@ public class JSR286Portlet extends UI { | |||
Link portletEdit = new Link(); | |||
Link portletMax = new Link(); | |||
Link someAction = null; | |||
Label userAgent = new Label(); | |||
Label screenWidth = new Label(); | |||
Label screenHeight = new Label(); | |||
private VerticalLayout main = new VerticalLayout(); | |||
@Override | |||
@@ -88,6 +91,16 @@ public class JSR286Portlet extends UI { | |||
main.addComponent(upload); | |||
possiblyChangedModeOrState(); | |||
userAgent.setCaption("User Agent"); | |||
main.addComponent(userAgent); | |||
screenWidth.setCaption("Screen width"); | |||
main.addComponent(screenWidth); | |||
screenHeight.setCaption("Screen height"); | |||
main.addComponent(screenHeight); | |||
getSession().addPortletListener(new DemoPortletListener()); | |||
} | |||
@@ -100,6 +113,11 @@ public class JSR286Portlet extends UI { | |||
VaadinPortletRequest request = (VaadinPortletRequest) VaadinPortletService | |||
.getCurrentRequest(); | |||
userAgent.setValue(getPage().getWebBrowser().getBrowserApplication()); | |||
screenWidth.setValue(String.valueOf(getPage().getBrowserWindowWidth())); | |||
screenHeight.setValue(String | |||
.valueOf(getPage().getBrowserWindowHeight())); | |||
boolean inViewMode = (request.getPortletMode() == PortletMode.VIEW); | |||
boolean inNormalState = (request.getWindowState() == WindowState.NORMAL); | |||
// Portlet up-and-running, enable stuff |
@@ -0,0 +1,111 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.layouts; | |||
import com.vaadin.annotations.Widgetset; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.tests.extensions.LayoutMemoryUsageIE8Extension; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.Button.ClickListener; | |||
import com.vaadin.ui.HasComponents; | |||
import com.vaadin.ui.Label; | |||
import com.vaadin.ui.VerticalLayout; | |||
@Widgetset("com.vaadin.tests.widgetset.TestingWidgetSet") | |||
public class IE8MeasuredSizeMemoryLeak extends AbstractTestUI { | |||
private boolean state = false; | |||
private HasComponents component1 = new VerticalLayout() { | |||
{ | |||
for (int i = 1; i <= 200; i++) { | |||
String idText = "ID:" + i; | |||
Label c = new Label(idText); | |||
c.setId(idText); | |||
addComponent(c); | |||
} | |||
} | |||
}; | |||
private HasComponents component2 = new VerticalLayout() { | |||
{ | |||
for (int i = 201; i <= 400; i++) { | |||
String idText = "ID:" + i; | |||
Label c = new Label(idText); | |||
c.setId(idText); | |||
addComponent(c); | |||
} | |||
} | |||
}; | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see com.vaadin.tests.components.AbstractTestUI#setup(com.vaadin.server. | |||
* VaadinRequest) | |||
*/ | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
new LayoutMemoryUsageIE8Extension().extend(this); | |||
VerticalLayout layout = new VerticalLayout(); | |||
setContent(layout); | |||
final VerticalLayout contentLayout = new VerticalLayout(); | |||
Button button = new Button("Toggle"); | |||
button.setId("toggle"); | |||
button.addClickListener(new ClickListener() { | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
contentLayout.removeAllComponents(); | |||
if (state) { | |||
contentLayout.addComponent(component1); | |||
} else { | |||
contentLayout.addComponent(component2); | |||
} | |||
state = !state; | |||
} | |||
}); | |||
layout.addComponent(button); | |||
layout.addComponent(contentLayout); | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see com.vaadin.tests.components.AbstractTestUI#getTestDescription() | |||
*/ | |||
@Override | |||
protected String getTestDescription() { | |||
return "IE8 leaks memory when components are added and removed"; | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
* @see com.vaadin.tests.components.AbstractTestUI#getTicketNumber() | |||
*/ | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 12688; | |||
} | |||
} |
@@ -0,0 +1,54 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.layouts; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.junit.Assert; | |||
import org.junit.Test; | |||
import org.openqa.selenium.JavascriptExecutor; | |||
import org.openqa.selenium.remote.DesiredCapabilities; | |||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||
public class IE8MeasuredSizeMemoryLeakTest extends MultiBrowserTest { | |||
@Test | |||
public void testMeasuredSizesMapCleaned() { | |||
openTestURL(); | |||
Assert.assertEquals("No extra measured sizes in the beginning", 3, | |||
getMeasuredSizesMapSize()); | |||
vaadinElementById("toggle").click(); | |||
Assert.assertEquals("Measured sizes after single toggle", 204, | |||
getMeasuredSizesMapSize()); | |||
vaadinElementById("toggle").click(); | |||
Assert.assertEquals("Measured sizes cleaned on toggle", 204, | |||
getMeasuredSizesMapSize()); | |||
} | |||
private int getMeasuredSizesMapSize() { | |||
JavascriptExecutor jsExec = (JavascriptExecutor) getDriver(); | |||
Number result = (Number) jsExec | |||
.executeScript("return window.vaadin.getMeasuredSizesCount();"); | |||
return result.intValue(); | |||
} | |||
@Override | |||
public List<DesiredCapabilities> getBrowsersToTest() { | |||
return Collections.singletonList(Browser.IE8.getDesiredCapabilities()); | |||
} | |||
} |
@@ -0,0 +1,75 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.push; | |||
import com.vaadin.annotations.Push; | |||
import com.vaadin.server.VaadinRequest; | |||
import com.vaadin.shared.ui.ui.Transport; | |||
import com.vaadin.tests.components.AbstractTestUI; | |||
import com.vaadin.ui.Button; | |||
import com.vaadin.ui.Button.ClickEvent; | |||
import com.vaadin.ui.Label; | |||
@Push(transport = Transport.STREAMING) | |||
public class StreamingReconnectWhilePushing extends AbstractTestUI { | |||
@Override | |||
protected void setup(VaadinRequest request) { | |||
Button button = new Button("Click Me"); | |||
button.addClickListener(new Button.ClickListener() { | |||
private Label label; | |||
@Override | |||
public void buttonClick(ClickEvent event) { | |||
if (label == null) { | |||
label = new Label(); | |||
label.setValue(getString(1000000)); | |||
addComponent(label); | |||
} else { | |||
label.setValue("." + label.getValue()); | |||
} | |||
} | |||
}); | |||
addComponent(button); | |||
} | |||
protected String getString(int len) { | |||
StringBuilder b = new StringBuilder(); | |||
for (int i = 0; i < len; i++) { | |||
if (i % 100 == 0) { | |||
b.append("\n"); | |||
} else { | |||
b.append('A'); | |||
} | |||
} | |||
return b.toString(); | |||
} | |||
@Override | |||
protected String getTestDescription() { | |||
return "Each push of the button sends about 1MB to the client. Press it a couple of times and a spinner will appear forever if reconnecting does not work."; | |||
} | |||
@Override | |||
protected Integer getTicketNumber() { | |||
return 13435; | |||
} | |||
} |
@@ -16,6 +16,7 @@ | |||
package com.vaadin.tests.tb3; | |||
import java.lang.annotation.Annotation; | |||
import java.lang.reflect.Method; | |||
import java.util.ArrayList; | |||
import java.util.Collection; | |||
@@ -83,12 +84,21 @@ public class TB3Runner extends BlockJUnit4ClassRunner { | |||
.getAnnotation(RunLocally.class).value() | |||
.getDesiredCapabilities()); | |||
} | |||
for (DesiredCapabilities capabilities : desiredCapabilites) { | |||
TestNameSuffix testNameSuffixProperty = findAnnotation( | |||
testClassInstance.getClass(), TestNameSuffix.class); | |||
for (DesiredCapabilities capabilities : desiredCapabilites) { | |||
// Find any methods marked with @Test. | |||
for (FrameworkMethod m : getTestClass().getAnnotatedMethods( | |||
Test.class)) { | |||
tests.add(new TB3Method(m.getMethod(), capabilities)); | |||
TB3Method method = new TB3Method(m.getMethod(), | |||
capabilities); | |||
if (testNameSuffixProperty != null) { | |||
method.setTestNameSuffix("-" | |||
+ System.getProperty(testNameSuffixProperty | |||
.property())); | |||
} | |||
tests.add(method); | |||
} | |||
} | |||
} catch (Exception e) { | |||
@@ -98,6 +108,27 @@ public class TB3Runner extends BlockJUnit4ClassRunner { | |||
return tests; | |||
} | |||
/** | |||
* Finds the given annotation in the given class or one of its super | |||
* classes. Return the first found annotation | |||
* | |||
* @param searchClass | |||
* @param annotationClass | |||
* @return | |||
*/ | |||
private <T extends Annotation> T findAnnotation(Class<?> searchClass, | |||
Class<T> annotationClass) { | |||
if (searchClass == Object.class) { | |||
return null; | |||
} | |||
if (searchClass.getAnnotation(annotationClass) != null) { | |||
return searchClass.getAnnotation(annotationClass); | |||
} | |||
return findAnnotation(searchClass.getSuperclass(), annotationClass); | |||
} | |||
/* | |||
* (non-Javadoc) | |||
* | |||
@@ -141,12 +172,17 @@ public class TB3Runner extends BlockJUnit4ClassRunner { | |||
private static class TB3Method extends FrameworkMethod { | |||
private DesiredCapabilities capabilities; | |||
private String testNameSuffix = ""; | |||
public TB3Method(Method method, DesiredCapabilities capabilities) { | |||
super(method); | |||
this.capabilities = capabilities; | |||
} | |||
public void setTestNameSuffix(String testNameSuffix) { | |||
this.testNameSuffix = testNameSuffix; | |||
} | |||
@Override | |||
public Object invokeExplosively(final Object target, Object... params) | |||
throws Throwable { | |||
@@ -156,9 +192,11 @@ public class TB3Runner extends BlockJUnit4ClassRunner { | |||
@Override | |||
public String getName() { | |||
return String.format("%s[%s]", getMethod().getName(), | |||
return String.format("%s[%s]", getMethod().getName() | |||
+ testNameSuffix, | |||
BrowserUtil.getUniqueIdentifier(capabilities)); | |||
} | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.tb3; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
/** | |||
* Defines a system property to be used as part of the test name | |||
*/ | |||
@Retention(RetentionPolicy.RUNTIME) | |||
public @interface TestNameSuffix { | |||
String property(); | |||
} |
@@ -0,0 +1,45 @@ | |||
/* | |||
* Copyright 2000-2013 Vaadin Ltd. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||
* use this file except in compliance with the License. You may obtain a copy of | |||
* the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
* License for the specific language governing permissions and limitations under | |||
* the License. | |||
*/ | |||
package com.vaadin.tests.widgetset.client; | |||
import com.vaadin.client.BrowserInfo; | |||
import com.vaadin.client.LayoutManager; | |||
import com.vaadin.client.LayoutManagerIE8; | |||
import com.vaadin.client.ServerConnector; | |||
import com.vaadin.client.extensions.AbstractExtensionConnector; | |||
import com.vaadin.shared.ui.Connect; | |||
import com.vaadin.tests.extensions.LayoutMemoryUsageIE8Extension; | |||
@Connect(LayoutMemoryUsageIE8Extension.class) | |||
public class LayoutMemoryUsageIE8ExtensionConnector extends | |||
AbstractExtensionConnector { | |||
@Override | |||
protected void extend(ServerConnector target) { | |||
if (BrowserInfo.get().isIE8()) { | |||
LayoutManagerIE8 manager = (LayoutManagerIE8) LayoutManager | |||
.get(getConnection()); | |||
configureGetMapSizeJS(manager); | |||
} | |||
} | |||
private native void configureGetMapSizeJS(LayoutManagerIE8 manager) | |||
/*-{ | |||
$wnd.vaadin.getMeasuredSizesCount = function() { | |||
return manager.@com.vaadin.client.LayoutManagerIE8::getMeasuredSizesMapSize()(); | |||
}; | |||
}-*/; | |||
} |