问题
The Selenium Javadoc for Actions.moveToElement
indicate that the meanings of the xOffset
and yOffset
arguments are as follows.
xOffset - Offset from the top-left corner. A negative value means coordinates left from the element.
yOffset - Offset from the top-left corner. A negative value means coordinates above the element.
Consider the following program, run on Linux against Firefox Quantum.
public class FirefoxTest {
public static void main(String[] args) {
// Set up driver
WebDriver driver = new FirefoxDriver();
JavascriptExecutor js = (JavascriptExecutor) driver;
driver.get("http://www.google.com");
WebElement element = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.name("q")));
// Perform a move and click action to see where it lands.
Actions moveAndClick = new Actions(driver).moveToElement(element,0,0).doubleClick();
moveAndClick.perform();
}
}
When the following program is run, the double-click occurs in the middle of the search box rather than at the top left corner (I know this because I injected JS to log the location of the click). Moreover, the following message is output in the terminal where the program is run.
org.openqa.selenium.interactions.Actions moveToElement
INFO: When using the W3C Action commands, offsets are from the center of element
Is it possible to programmatically determine whether the offsets are from the center or the top-left corner of the element for Actions.moveToElement
?
回答1:
To start with, when invoking GeckoDriver the first set of logs confirms that dialect being W3C
as follows:
org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
You are correct as the Java Docs for moveToElement() still mentions that:
public Actions moveToElement(WebElement target, int xOffset, int yOffset)
Description:
Moves the mouse to an offset from the top-left corner of the element. The element is scrolled into view and its location is calculated using getBoundingClientRect.
Parameters:
target - element to move to.
xOffset - Offset from the top-left corner. A negative value means coordinates left from the element.
yOffset - Offset from the top-left corner. A negative value means coordinates above the element.
Returns:
A self reference.
I am able to reproduce your issue as follows:
Code Block:
new Actions(driver).moveToElement(element,0,0).doubleClick().build().perform();
Trace Logs:
Oct 16, 2018 6:06:13 PM org.openqa.selenium.interactions.Actions moveToElement INFO: When using the W3C Action commands, offsets are from the center of element 1539693373141 webdriver::server DEBUG -> POST /session/180ab0f0-21a3-4e38-8c92-d208fac77827/actions {"actions":[{"id":"default mouse","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"duration":100,"x":0,"y":0,"type":"pointerMove","origin":{"ELEMENT":"774efad2-7ee0-40a3-bcaa-3a4d5fcff47b","element-6066-11e4-a52e-4f735466cecf":"774efad2-7ee0-40a3-bcaa-3a4d5fcff47b"}},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"},{"button":0,"type":"pointerDown"},{"button":0,"type":"pointerUp"}]}]} 1539693373166 Marionette TRACE 0 -> [0,5,"WebDriver:PerformActions",{"actions":[{"actions":[{"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"774e ... pointerDown"},{"button":0,"type":"pointerUp"}],"id":"default mouse","parameters":{"pointerType":"mouse"},"type":"pointer"}]}]
As @Andreas pointed out in the discussion offsets are from the center of element instead of from the top-left corner @FlorentB. clearly pointed that:
As per /session/:sessionId/moveto in JsonWireProtocol specification it was mentioned:
/session/:sessionId/moveto POST /session/:sessionId/moveto Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view. URL Parameters: :sessionId - ID of the session to route the command to. JSON Parameters: element - {string} Opaque ID assigned to the element to move to, as described in the WebElement JSON Object. If not specified or is null, the offset is relative to current position of the mouse. xoffset - {number} X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element. yoffset - {number} Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
As per the Pointer Actions section within WebDriver W3C Editor's Draft it is mentioned that:
An object that represents a web element
Let element be equal to the result of trying to get a known connected element with argument origin.
Let x element and y element be the result of calculating the in-view center point of element.
Let x equal x element + x offset, and y equal y element + y offset.
In-view center point
An element’s in-view center point is the origin position of the rectangle that is the intersection between the element’s first DOM client rectangle and the initial viewport. Given an element that is known to be in view, it is calculated as:
- Let rectangle be the first element of the DOMRect sequence returned by calling getClientRects on element.
- Let left be (max(0, min(x coordinate, x coordinate + width dimension))).
- Let right be (min(innerWidth, max(x coordinate, x coordinate + width dimension))).
- Let top be (max(0, min(y coordinate, y coordinate + height dimension))).
- Let bottom be (min(innerHeight, max(y coordinate, y coordinate + height dimension))).
- Let x be (0.5 × (left + right)).
- Let y be (0.5 × (top + bottom)).
- Return x and y as a pair.
So it is can be concluded that the offsets are from the center but the Jave Docs are yet to be updated.
来源:https://stackoverflow.com/questions/51974620/is-it-possible-to-programmatically-determine-whether-w3c-action-commands-are-use