What happened?
When the user attempts to get a web element's location and size, the code will crash because the command is not supported in W3C mode.
This is due to the fact that unlike JWP, those commands are not supported, and W3C only allows getRect as per spec.
https://w3c.github.io/webdriver/#get-element-rect
Only JWP (not W3C) allows those two as supported commands:
https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidelementidlocation
https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidelementidsize
The code in Selenium 3 should have checked for W3C mode like the Python implementation does, and choose accordingly. Selenium 4 is W3C mode purely and the code should have been migrated to support only that. It is currently still using JWP commands.
This means that the Python and Java implementations are not in sync, and the Java implementation is incorrect. The getLocation and getSize code for Selenium 4 could just use the getRect as a function in both implementations since that's all that's available, and wrap around it to extract the relevant data.
Java
Python

---

The solution for Selenium 4 Java (and similarly Python) can just be something like:
@Override
@SuppressWarnings({"unchecked"})
public Point getLocation() {
Rectangle rect = getRect();
return rect.getPoint();
}
@Override
@SuppressWarnings({"unchecked"})
public Dimension getSize() {
Rectangle rect = getRect();
return rect.getDimension();
}
@Override
@SuppressWarnings({"unchecked"})
public Rectangle getRect() {
Response response = execute(DriverCommand.GET_ELEMENT_RECT(id));
Map<String, Object> rawRect = (Map<String, Object>) response.getValue();
int x = ((Number) rawRect.get("x")).intValue();
int y = ((Number) rawRect.get("y")).intValue();
int width = ((Number) rawRect.get("width")).intValue();
int height = ((Number) rawRect.get("height")).intValue();
return new Rectangle(x, y, height, width);
}
or for consistency, this:
@Override
@SuppressWarnings({"unchecked"})
public Point getLocation() {
Response response = execute(DriverCommand.GET_ELEMENT_RECT(id));
Map<String, Object> rawPoint = (Map<String, Object>) response.getValue();
int x = ((Number) rawPoint.get("x")).intValue();
int y = ((Number) rawPoint.get("y")).intValue();
return new Point(x, y);
}
@Override
@SuppressWarnings({"unchecked"})
public Dimension getSize() {
Response response = execute(DriverCommand.GET_ELEMENT_RECT(id));
Map<String, Object> rawSize = (Map<String, Object>) response.getValue();
int width = ((Number) rawSize.get("width")).intValue();
int height = ((Number) rawSize.get("height")).intValue();
return new Dimension(width, height);
}
@Override
@SuppressWarnings({"unchecked"})
public Rectangle getRect() {
Response response = execute(DriverCommand.GET_ELEMENT_RECT(id));
Map<String, Object> rawRect = (Map<String, Object>) response.getValue();
int x = ((Number) rawRect.get("x")).intValue();
int y = ((Number) rawRect.get("y")).intValue();
int width = ((Number) rawRect.get("width")).intValue();
int height = ((Number) rawRect.get("height")).intValue();
return new Rectangle(x, y, height, width);
}
In Selenium 3 this was a parameterized choice of one or the other based on whether the test was run in JWP or W3C modes. in Selenium 4, those two functions are basically just helper/wrapper functions.
How can we reproduce the issue?
Visit a webpage (Selenium) or a WebView (Appium) in W3C mode, and attempt to get the size or location of a WebElement.
webElement.getLocation();
webElement.getSize();
The workaround is to use the API directly as the fix above would suggest and use:
webElement.getRect().getPoint();
webElement.getRect().getDimension();
The problem with this is that a lot of teams that are using this for their testing and want to migrate already have much of their code written in the former use case. It would ease the friction of migration and save lost hours of debugging time to correct the implementation and allow teams to use their code in its existing state without the workaround.
Relevant log output
Description: "Cannot call non W3C standard command while in W3C mode "
When using getLocation()
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:250)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:41)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285)
at io.appium.java_client.DefaultGenericMobileElement.execute(DefaultGenericMobileElement.java:45)
at io.appium.java_client.MobileElement.execute(MobileElement.java:1)
at io.appium.java_client.android.AndroidElement.execute(AndroidElement.java:1)
at org.openqa.selenium.remote.RemoteWebElement.getLocation(RemoteWebElement.java:337)
--
When using getSize()
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:250)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:41)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:285)
at io.appium.java_client.DefaultGenericMobileElement.execute(DefaultGenericMobileElement.java:45)
at io.appium.java_client.MobileElement.execute(MobileElement.java:1)
at io.appium.java_client.android.AndroidElement.execute(AndroidElement.java:1)
at org.openqa.selenium.remote.RemoteWebElement.getSize(RemoteWebElement.java:346)
Operating System
Not Applicable but on macOS against Android and iOS
Selenium version
Java Selenium 3 and 4
What are the browser(s) and version(s) where you see this issue?
WebView
What are the browser driver(s) and version(s) where you see this issue?
Available on Request
Are you using Selenium Grid?
No
What happened?
When the user attempts to get a web element's location and size, the code will crash because the command is not supported in W3C mode.
This is due to the fact that unlike JWP, those commands are not supported, and W3C only allows getRect as per spec.
https://w3c.github.io/webdriver/#get-element-rect
Only JWP (not W3C) allows those two as supported commands:
https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidelementidlocation
https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidelementidsize
The code in Selenium 3 should have checked for W3C mode like the Python implementation does, and choose accordingly. Selenium 4 is W3C mode purely and the code should have been migrated to support only that. It is currently still using JWP commands.
This means that the Python and Java implementations are not in sync, and the Java implementation is incorrect. The
getLocationandgetSizecode for Selenium 4 could just use thegetRectas a function in both implementations since that's all that's available, and wrap around it to extract the relevant data.Java
Python

---The solution for Selenium 4 Java (and similarly Python) can just be something like:
or for consistency, this:
In Selenium 3 this was a parameterized choice of one or the other based on whether the test was run in JWP or W3C modes. in Selenium 4, those two functions are basically just helper/wrapper functions.
How can we reproduce the issue?
Visit a webpage (Selenium) or a WebView (Appium) in W3C mode, and attempt to get the size or location of a
WebElement.webElement.getLocation();webElement.getSize();The workaround is to use the API directly as the fix above would suggest and use:
webElement.getRect().getPoint();webElement.getRect().getDimension();The problem with this is that a lot of teams that are using this for their testing and want to migrate already have much of their code written in the former use case. It would ease the friction of migration and save lost hours of debugging time to correct the implementation and allow teams to use their code in its existing state without the workaround.
Relevant log output
Description: "Cannot call non W3C standard command while in W3C mode "
When using
getLocation()--
When using
getSize()Operating System
Not Applicable but on macOS against Android and iOS
Selenium version
Java Selenium 3 and 4
What are the browser(s) and version(s) where you see this issue?
WebView
What are the browser driver(s) and version(s) where you see this issue?
Available on Request
Are you using Selenium Grid?
No