/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.contextclick;
import static org.junit.Assert.assertEquals;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import com.vaadin.testbench.elements.AbstractComponentElement;
import com.vaadin.testbench.elements.ButtonElement;
import com.vaadin.testbench.parallel.BrowserUtil;
import com.vaadin.testbench.parallel.TestCategory;
import com.vaadin.tests.tb3.MultiBrowserTest;
@TestCategory("contextclick")
public abstract class AbstractContextClickTest extends MultiBrowserTest {
private Pattern defaultLog = Pattern
.compile("[0-9]+. ContextClickEvent: [(]([0-9]+), ([0-9]+)[)]");
@Override
protected boolean useNativeEventsForIE() {
return false;
}
@Override
public List<DesiredCapabilities> getBrowsersToTest() {
return getBrowsersSupportingContextMenu();
}
@Before
public void setUp() {
openTestURL();
}
@Test
public void testDefaultListener() {
addOrRemoveDefaultListener();
assertDefaultContextClickListener(1);
}
protected void assertNoContextClickHandler() {
AbstractComponentElement component = $(AbstractComponentElement.class)
.id("testComponent");
String log = getLogRow(0);
contextClick(component);
assertEquals("Log entry without a context click listener.", log,
getLogRow(0));
}
protected void assertDefaultContextClickListener(int index) {
AbstractComponentElement component = $(AbstractComponentElement.class)
.id("testComponent");
int x = 20;
int y = 20;
contextClick(component, x, y);
Point l = component.getLocation();
Matcher matcher = defaultLog.matcher(getLogRow(0));
Assert.assertTrue(
"Log row content did not match default listener output: "
+ getLogRow(0),
matcher.find());
int xCoord = Integer.parseInt(matcher.group(1));
int yCoord = Integer.parseInt(matcher.group(2));
int xExpected = l.getX() + x;
int yExpected = l.getY() + y;
Assert.assertTrue(
"X Coordinate differs too much from expected. Expected: "
+ xExpected + ", actual: " + xCoord,
Math.abs(xExpected - xCoord) <= 1);
Assert.assertTrue(
"Y Coordinate differs too much from expected. Expected: "
+ yExpected + ", actual: " + yCoord,
Math.abs(yExpected - yCoord) <= 1);
}
protected void addOrRemoveDefaultListener() {
$(ButtonElement.class).caption("Add/Remove default listener").first()
.click();
}
protected void addOrRemoveTypedListener() {
$(ButtonElement.class).caption("Add/Remove typed listener").first()
.click();
}
/**
* Performs a context click on given element at coordinates 10, 10 followed
* by a regular click. This prevents browser context menu from blocking
* future operations.
*
* @param e
* web element
*/
protected void contextClick(WebElement e) {
contextClick(e, 10, 10);
}
/**
* Performs a context click on given element at given coordinates followed
* by a regular click. This prevents browser context menu from blocking
* future operations.
*
* @param e
* web element
* @param xCoord
* x coordinate relative to the top-left corner of the element
* @param yCoord
* y coordinate relative to the top-left corner of the element
*/
protected void contextClick(WebElement e, int xCoord, int yCoord) {
if (BrowserUtil.isFirefox(getDesiredCapabilities())) {
// Workaround for Selenium/TB and Firefox 45 issue
int x = e.getLocation().getX() + xCoord;
int y = e.getLocation().getY() + yCoord;
getCommandExecutor().executeScript(
"var ev = document.createEvent('MouseEvents'); ev.initMouseEvent('contextmenu', true, true, document.defaultView, 1, arguments[1], arguments[2], arguments[1], arguments[2], false, false, false, false, 2, null); arguments[0].dispatchEvent(ev);",
e, x, y);
// make sure browser context menu does not block the test
getCommandExecutor().executeScript(
"var ev = document.createEvent('MouseEvents'); ev.initMouseEvent('click', true, true, document.defaultView, 1, arguments[1]-5, arguments[2]-5, arguments[1]-5, arguments[2]-5, false, false, false, false, 1, null); arguments[0].dispatchEvent(ev);",
e, x, y);
} else {
new Actions(getDriver()).moveToElement(e, xCoord, yCoord)
.contextClick().moveByOffset(-5, -5).click().perform();
}
}
}