Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public void testDefaultValues() {
Assertions.assertEquals(false,
Parameters.isScreenshotComparisonCursorDetection());
Assertions.assertFalse(Parameters.isHeadless());
Assertions.assertFalse(Parameters.isUseJavascriptClick());
Assertions.assertEquals(
ClientConfig.defaultConfig().readTimeout().toSeconds(),
Parameters.getReadTimeout());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.testUI;

import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.NativeButton;
import com.vaadin.flow.router.Route;

@Route("ClickCountView")
public class ClickCountView extends Div {

public ClickCountView() {
NativeButton button = new NativeButton("Click me");
button.setId("click-target");

Div log = new Div();
log.setId("click-count");

button.getElement().addEventListener("click", e -> {
log.setText(String
.valueOf(e.getEventData().get("event.detail").intValue()));
}).addEventData("event.detail");

add(button, log);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Copyright (C) 2000-2026 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See <https://vaadin.com/commercial-license-and-service-terms> for the full
* license.
*/
package com.vaadin.tests.elements;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;

import com.vaadin.flow.component.Component;
import com.vaadin.testUI.ClickCountView;
import com.vaadin.testbench.BrowserTest;
import com.vaadin.testbench.TestBenchElement;
import com.vaadin.tests.AbstractBrowserTB9Test;

public class ClickCountIT extends AbstractBrowserTB9Test {

@Override
protected Class<? extends Component> getTestView() {
return ClickCountView.class;
}

@BeforeEach
public void open() {
openTestURL();
}

@BrowserTest
public void click_hasClickCountOne() {
TestBenchElement button = $(NativeButtonElement.class)
.id("click-target");
button.click();
Assertions.assertEquals("1", $("div").id("click-count").getText());
}

@BrowserTest
public void clickWithCoordinates_hasClickCountOne() {
TestBenchElement button = $(NativeButtonElement.class)
.id("click-target");
button.click(0, 0);
Assertions.assertEquals("1", $("div").id("click-count").getText());
}

@BrowserTest
public void doubleClick_hasClickCountTwo() {
TestBenchElement button = $(NativeButtonElement.class)
.id("click-target");
button.doubleClick();
Assertions.assertEquals("2", $("div").id("click-count").getText());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class Parameters {
private static int readTimeout;
private static int hubPort;
private static String[] chromeOptions;
private static boolean useJavascriptClick;
static {
isDebug = getSystemPropertyBoolean("debug", false);

Expand Down Expand Up @@ -68,6 +69,8 @@ public class Parameters {
(int) ClientConfig.defaultConfig().readTimeout().toSeconds());
hubPort = getSystemPropertyInt("hubPort", 4444);
setChromeOptions(getSystemPropertyString("chromeOptions", null));
useJavascriptClick = getSystemPropertyBoolean("useJavascriptClick",
false);
}

/**
Expand Down Expand Up @@ -564,4 +567,35 @@ public static String[] getChromeOptions() {
public static int getReadTimeout() {
return readTimeout;
}

/**
* Returns whether {@link TestBenchElement#click()} should use JavaScript
* instead of Selenium Actions.
* <p>
* JavaScript click avoids "element not clickable at point" issues but does
* not correctly simulate a real user interaction in the browser (e.g.,
* browser event properties such as click count may be missing or
* incorrect).
*
* @return {@code true} if JavaScript click is used by default,
* {@code false} otherwise
*/
public static boolean isUseJavascriptClick() {
return useJavascriptClick;
}

/**
* Sets whether {@link TestBenchElement#click()} should use JavaScript
* instead of Selenium Actions.
* <p>
* Can also be set with the system property
* {@code com.vaadin.testbench.Parameters.useJavascriptClick=true}.
*
* @param useJavascriptClick
* {@code true} to use JavaScript click, {@code false} to use
* Selenium Actions
*/
public static void setUseJavascriptClick(boolean useJavascriptClick) {
Parameters.useJavascriptClick = useJavascriptClick;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,16 +191,39 @@ public boolean isFocused() {

@Override
public void click() {
// JS call to click does not focus element, hence ensure focus
if (Parameters.isUseJavascriptClick()) {
javascriptClick();
} else {
autoScrollIntoView();
waitForVaadin();
new Actions(getDriver()).click(wrappedElement).build().perform();
}
}

/**
* Clicks the element using JavaScript rather than Selenium Actions.
* <p>
* This avoids "element not clickable at point" issues that can occur when
* the element is behind an overlay or otherwise not directly reachable by
* Selenium, but it does not correctly simulate a real user interaction in
* the browser (e.g., browser event properties such as click count may be
* missing or incorrect).
* <p>
* Prefer {@link #click()} for normal use. Use this method only when you
* need to click an element that Selenium cannot reach directly.
* <p>
* To use this method globally as the default for {@link #click()}, set the
* system property
* {@code com.vaadin.testbench.Parameters.useJavascriptClick=true} or call
* {@link Parameters#setUseJavascriptClick(boolean)}.
*/
public void javascriptClick() {
focus();
try {
// Avoid strange "element not clickable at point" problems
callFunction("click");
} catch (Exception e) {
if (e.getMessage()
if (e.getMessage() != null && e.getMessage()
.contains("Inspected target navigated or closed")) {
// This happens with chromedriver although e.g. navigation
// succeeds
return;
}
// SVG elements and maybe others do not have a 'click' method
Expand Down
Loading