Change-Id: I412ba219f31567ebba019b7d6ce4db4af9be9363tags/7.5.0.beta1
<html> | |||||
<head> | |||||
<title>IEJumpTest</title> | |||||
</head> | |||||
<!-- This is for testing Vaadin UI in iFrame (test class TableInIframeRowClickScrollJumpTest, for ticket #15294 --> | |||||
<body> | |||||
<div style="font-size: 4px">test div</div> | |||||
<iframe id="test-iframe-0" src="/run/com.vaadin.tests.components.table.TableBlurFocus" width="100%" height="2000px" style="visibility: visible;"> | |||||
</iframe> | |||||
</body> | |||||
</html> |
Style style = getElement().getStyle(); | Style style = getElement().getStyle(); | ||||
style.setProperty("zoom", "1"); | style.setProperty("zoom", "1"); | ||||
style.setPosition(Position.RELATIVE); | style.setPosition(Position.RELATIVE); | ||||
browserInfo = BrowserInfo.get(); | |||||
} | } | ||||
private DivElement focusElement; | private DivElement focusElement; | ||||
private BrowserInfo browserInfo; | |||||
public FocusableScrollPanel(boolean useFakeFocusElement) { | public FocusableScrollPanel(boolean useFakeFocusElement) { | ||||
this(); | this(); | ||||
style.setPosition(Position.FIXED); | style.setPosition(Position.FIXED); | ||||
style.setTop(0, Unit.PX); | style.setTop(0, Unit.PX); | ||||
style.setLeft(0, Unit.PX); | style.setLeft(0, Unit.PX); | ||||
if (browserInfo.isIE()) { | |||||
// for #15294: artificially hide little bit more the | |||||
// focusElement, otherwise IE will make the window to scroll | |||||
// into it when focused | |||||
style.setLeft(-999, Unit.PX); | |||||
} | |||||
getElement().appendChild(focusElement); | getElement().appendChild(focusElement); | ||||
/* Sink from focusElemet too as focusa and blur don't bubble */ | /* Sink from focusElemet too as focusa and blur don't bubble */ | ||||
DOM.sinkEvents(focusElement, Event.FOCUSEVENTS); | DOM.sinkEvents(focusElement, Event.FOCUSEVENTS); |
/* | |||||
* 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.table; | |||||
import java.util.Map; | |||||
import com.vaadin.event.FieldEvents.BlurEvent; | |||||
import com.vaadin.event.FieldEvents.BlurListener; | |||||
import com.vaadin.event.FieldEvents.FocusEvent; | |||||
import com.vaadin.event.FieldEvents.FocusListener; | |||||
import com.vaadin.server.VaadinRequest; | |||||
import com.vaadin.tests.components.AbstractTestUIWithLog; | |||||
import com.vaadin.ui.Button; | |||||
import com.vaadin.ui.Button.ClickEvent; | |||||
import com.vaadin.ui.Button.ClickListener; | |||||
import com.vaadin.ui.Label; | |||||
import com.vaadin.ui.Notification; | |||||
import com.vaadin.ui.Table; | |||||
/** | |||||
* Tests that previously focused component's blur event happens before any | |||||
* variable changes in the focused Table. | |||||
* | |||||
* @author Vaadin Ltd | |||||
*/ | |||||
public class TableBlurFocus extends AbstractTestUIWithLog { | |||||
enum Columns { | |||||
COLUMN1, COLUMN2, COLUMN3, COLUMN4, COLUMN5 | |||||
} | |||||
private int count = 0; | |||||
private Button focusButton; | |||||
@Override | |||||
protected void setup(VaadinRequest request) { | |||||
System.out | |||||
.println("TableBlurFocus/TableInIframeRowClickScrollJumpTest"); | |||||
Button button = new Button("click to focus"); | |||||
button.addFocusListener(new FocusListener() { | |||||
@Override | |||||
public void focus(FocusEvent event) { | |||||
log("focus"); | |||||
} | |||||
}); | |||||
button.addBlurListener(new BlurListener() { | |||||
@Override | |||||
public void blur(BlurEvent event) { | |||||
log("blur"); | |||||
} | |||||
}); | |||||
final Button scrollButton = new Button( | |||||
"focus lowest button to scroll down"); | |||||
scrollButton.setId("scroll-button"); | |||||
scrollButton.addClickListener(new ClickListener() { | |||||
@Override | |||||
public void buttonClick(ClickEvent event) { | |||||
focusButton.focus(); | |||||
} | |||||
}); | |||||
Label spacerLabel = new Label("spacer"); | |||||
spacerLabel.setHeight("300px"); | |||||
addComponent(button); | |||||
addComponent(scrollButton); | |||||
addComponent(createTable()); | |||||
addComponent(spacerLabel); | |||||
addComponent(focusButton = new Button("for focus")); | |||||
focusButton.setId("focus-button"); | |||||
focusButton.addFocusListener(new FocusListener() { | |||||
@Override | |||||
public void focus(FocusEvent event) { | |||||
focusButton.setCaption("focused"); | |||||
} | |||||
}); | |||||
} | |||||
private Table createTable() { | |||||
Table table = new Table() { | |||||
@Override | |||||
public void changeVariables(Object source, | |||||
Map<String, Object> variables) { | |||||
log("variable change"); | |||||
super.changeVariables(source, variables); | |||||
} | |||||
}; | |||||
table.setSelectable(true); | |||||
table.setImmediate(true); | |||||
table.addContainerProperty(Columns.COLUMN1, String.class, " "); | |||||
table.addContainerProperty(Columns.COLUMN2, Label.class, null); | |||||
table.addContainerProperty(Columns.COLUMN3, Button.class, null); | |||||
table.addContainerProperty(Columns.COLUMN4, String.class, " "); | |||||
table.setColumnCollapsingAllowed(true); | |||||
table.setColumnCollapsible(Columns.COLUMN4, true); | |||||
table.setColumnCollapsed(Columns.COLUMN4, true); | |||||
table.setSortEnabled(true); | |||||
table.setFooterVisible(true); | |||||
table.setPageLength(14); | |||||
table.addGeneratedColumn(Columns.COLUMN5, new Table.ColumnGenerator() { | |||||
@Override | |||||
public Object generateCell(Table source, Object itemId, | |||||
Object columnId) { | |||||
return "Generated"; | |||||
} | |||||
}); | |||||
table.setColumnHeader(Columns.COLUMN1, "Column"); | |||||
for (int x = 0; x < 120; x++) { | |||||
final Label buttonLabel = new Label("Not clicked"); | |||||
Button button = new Button("Click me?", new Button.ClickListener() { | |||||
@Override | |||||
public void buttonClick(Button.ClickEvent event) { | |||||
++count; | |||||
buttonLabel.setValue("Clicked " + count + " times"); | |||||
Notification.show("Clicked!"); | |||||
} | |||||
}); | |||||
table.addItem(new Object[] { "entryString" + x, buttonLabel, | |||||
button, " " }, "entryID" + x); | |||||
} | |||||
return table; | |||||
} | |||||
@Override | |||||
protected String getTestDescription() { | |||||
return "Click button to focus, then click Table header. Blur event should arrive before the next variable change."; | |||||
} | |||||
@Override | |||||
protected Integer getTicketNumber() { | |||||
return 15294; | |||||
} | |||||
} |
/* | |||||
* 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.table; | |||||
import static org.hamcrest.MatcherAssert.assertThat; | |||||
import static org.junit.Assert.assertEquals; | |||||
import java.util.Arrays; | |||||
import org.junit.Test; | |||||
import org.openqa.selenium.By; | |||||
import com.vaadin.testbench.elements.ButtonElement; | |||||
import com.vaadin.testbench.elements.TableElement; | |||||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||||
public class TableBlurFocusTest extends MultiBrowserTest { | |||||
@Test | |||||
public void testBlurAndFocus() throws InterruptedException { | |||||
openTestURL(); | |||||
waitForElementPresent(By.className("v-button")); | |||||
assertAnyLogText("1. variable change"); | |||||
assertEquals("Unexpected column header,", "COLUMN2", | |||||
$(TableElement.class).first().getHeaderCell(1).getCaption()); | |||||
assertEquals("Unexpected button caption,", "click to focus", | |||||
$(ButtonElement.class).first().getCaption()); | |||||
$(ButtonElement.class).first().click(); | |||||
assertAnyLogText("2. focus", "3. focus"); | |||||
$(TableElement.class).first().getHeaderCell(1).click(); | |||||
assertAnyLogText("3. blur", "4. blur"); | |||||
} | |||||
private void assertAnyLogText(String... texts) { | |||||
assertThat(String.format( | |||||
"Correct log text was not found, expected any of %s", | |||||
Arrays.asList(texts)), logContainsAnyText(texts)); | |||||
} | |||||
private boolean logContainsAnyText(String... texts) { | |||||
for (String text : texts) { | |||||
if (logContainsText(text)) { | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
} |
/* | |||||
* 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.table; | |||||
import static org.hamcrest.MatcherAssert.assertThat; | |||||
import java.util.List; | |||||
import org.junit.Test; | |||||
import org.openqa.selenium.JavascriptExecutor; | |||||
import org.openqa.selenium.WebElement; | |||||
import com.vaadin.testbench.By; | |||||
import com.vaadin.testbench.elements.ButtonElement; | |||||
import com.vaadin.testbench.elements.TableElement; | |||||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||||
/** | |||||
* For testing that UI scroll does not jump back to up when: 1. UI is in iframe | |||||
* 2. the window scrolled down 3. and table is clicked | |||||
* | |||||
* @since | |||||
* @author Vaadin Ltd | |||||
*/ | |||||
public class TableInIframeRowClickScrollJumpTest extends MultiBrowserTest { | |||||
private static final String TEST_URL = "statictestfiles/TableInIframeRowClickScrollJumpTest.html"; | |||||
@Test | |||||
public void testRowClicking_WhenScrolledDown_shouldMaintainScrollPosition() | |||||
throws InterruptedException { | |||||
System.out.println(">>>" + getBaseURL() + TEST_URL); | |||||
driver.get(getUrl()); | |||||
// using non-standard way because of iframe | |||||
sleep(4000); | |||||
// make sure we are in the "main content" | |||||
driver.switchTo().defaultContent(); | |||||
sleep(2000); | |||||
switchIntoIframe(); | |||||
// using non-standard way because of iframe | |||||
waitForElementVisible(By.id("scroll-button")); | |||||
ButtonElement scrollbutton = $(ButtonElement.class).id("scroll-button"); | |||||
scrollbutton.click(); | |||||
// using non-standard way because of iframe | |||||
sleep(1000); | |||||
Long scrollPosition = getWindowsScrollPosition(); | |||||
assertThat("Scroll position should be greater than 100 (it was " | |||||
+ scrollPosition + ")", scrollPosition > 100); | |||||
TableElement table = $(TableElement.class).first(); | |||||
table.getRow(13).getCell(0).click(); | |||||
// using non-standard way because of iframe | |||||
sleep(1000); | |||||
Long scrollPosition2 = getWindowsScrollPosition(); | |||||
assertThat("Scroll position should stay about the same. Old was " | |||||
+ scrollPosition + " and new one " + scrollPosition2, | |||||
Math.abs(scrollPosition - scrollPosition2) < 10); | |||||
} | |||||
private String getUrl() { | |||||
String url; | |||||
// using non-standard way because of iframe | |||||
if (getBaseURL().charAt(getBaseURL().length() - 1) == '/') { | |||||
url = getBaseURL() + TEST_URL; | |||||
} else { | |||||
// this one is for gerrit's teamcity :( | |||||
url = getBaseURL() + '/' + TEST_URL; | |||||
} | |||||
return url; | |||||
} | |||||
public void switchIntoIframe() { | |||||
List<WebElement> frames = driver.findElements(By.tagName("iframe")); | |||||
assertThat("No frames was found", frames.size() > 0); | |||||
driver.switchTo().frame(frames.get(0)); | |||||
} | |||||
private Long getWindowsScrollPosition() { | |||||
// measure scroll pos in the main window | |||||
driver.switchTo().defaultContent(); | |||||
JavascriptExecutor executor = (JavascriptExecutor) driver; | |||||
Long value = (Long) executor | |||||
.executeScript("if (window.pageYOffset) return window.pageYOffset;else if (window.document.documentElement.scrollTop) return window.document.documentElement.scrollTop;else return window.document.body.scrollTop;"); | |||||
// back to the iframe | |||||
switchIntoIframe(); | |||||
return value; | |||||
} | |||||
@Override | |||||
// using non-standard way because of iframe | |||||
protected void closeApplication() { | |||||
if (driver != null) { | |||||
try { | |||||
driver.get(getUrl() + "?closeApplication"); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
} | |||||
} |