geckodriver
geckodriver copied to clipboard
Getting element property for invalid property throws error
System
- Version: 0.29
- Platform: Mac
- Firefox: 85.0.2
- Selenium: 4 beta 1 (Ruby)
I'm not sure either Chrome or Firefox is doing the right thing here; I think the right answer is a null response? https://w3c.github.io/webdriver/#get-element-property https://github.com/web-platform-tests/wpt/blob/master/webdriver/tests/get_element_property/get.py#L45
Testcase
driver = Selenium::WebDriver.for :firefox
driver.navigate.to 'http://watir.com/examples/forms_with_input_elements.html'
element = driver.find_element(id: 'delete_user_submit')
element.property('style')
Stacktrace
2021-02-22 11:29:36 INFO Selenium -> POST session/bf2cd1ce-9779-a240-b625-264a9efdf82d/url
2021-02-22 11:29:36 INFO Selenium >>> http://127.0.0.1:4444/session/bf2cd1ce-9779-a240-b625-264a9efdf82d/url | {"url":"http://watir.com/examples/forms_with_input_elements.html"}
2021-02-22 11:29:37 INFO Selenium <- {"value":null}
2021-02-22 11:29:37 INFO Selenium -> POST session/bf2cd1ce-9779-a240-b625-264a9efdf82d/element
2021-02-22 11:29:37 INFO Selenium >>> http://127.0.0.1:4444/session/bf2cd1ce-9779-a240-b625-264a9efdf82d/element | {"using":"css selector","value":"#delete_user_submit"}
2021-02-22 11:29:37 INFO Selenium <- {"value":{"element-6066-11e4-a52e-4f735466cecf":"7213a30f-2d84-6e4f-94ed-8a09175dbe3f"}}
2021-02-22 11:29:37 INFO Selenium -> GET session/bf2cd1ce-9779-a240-b625-264a9efdf82d/element/7213a30f-2d84-6e4f-94ed-8a09175dbe3f/property/style
2021-02-22 11:29:37 INFO Selenium <- {"value":{"error":"unknown error","message":"Failed to find value field","stacktrace":""}}
For comparison, Chrome returns:
2021-02-22 11:32:52 INFO Selenium <- {"value":["border-top-width","border-right-width","border-bottom-width","border-left-width","border-top-style","border-right-style","border-bottom-style","border-left-style","border-top-color","border-right-color","border-bottom-color","border-left-color","border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"]}
So the comparison with Chrome is not identical. Why does the style exist in Chrome but not Firefox? Mind checking with DevTools what's different for that page?
Also what does Chrome return for eg. element.property('style-not-existent')?
Also here is the code from Marionette that handles getting the property value.
So the listed failure message comes from geckodriver.
@titusfortner can you please enable trace logging for Marionette so that we can see what Marionette actually returns in that case? Thanks.
Looks like style also exists in Firefox, but there are some null values that might not be getting handled corectly:
2021-02-22 14:05:51 INFO Selenium -> GET session/4ddd3235-b81b-654d-8420-997f5b15d7de/element/ca535828-4a24-7749-83c8-eebf53cc0076/property/style
1614024351715 webdriver::server DEBUG -> GET /session/4ddd3235-b81b-654d-8420-997f5b15d7de/element/ca535828-4a24-7749-83c8-eebf53cc0076/property/style
1614024351716 Marionette DEBUG 0 -> [0,5,"WebDriver:GetElementProperty",{"id":"ca535828-4a24-7749-83c8-eebf53cc0076","name":"style"}]
1614024351731 Marionette DEBUG 0 <- [1,5,null,{"0":"border-top-color","1":"border-top-style","2":"border-top-width","3":"border-right-color","4":"border-right-st ... ,"setProperty":{},"removeProperty":{},"cssText":"border: 4px solid red;","length":17,"parentRule":null,"getCSSImageURLs":{}}]
1614024351733 webdriver::server DEBUG <- 500 Internal Server Error {"value":{"error":"unknown error","message":"Failed to find value field","stacktrace":""}}
2021-02-22 14:05:51 INFO Selenium <- {"value":{"error":"unknown error","message":"Failed to find value field","stacktrace":""}}
Oh, and I think I was incorrectly considering style to be attribute-only, but I guess the matching property is an object instead of a string? In which case I have no idea what the response is supposed to look like.
@titusfortner any chance that you could see what chromedriver returns as payload for the "Get Element Property" command?
Note that I cannot reproduce the behavior by the steps as given in the original comment. It works fine and geckodriver returns the full object. Here the Python code that I run:
driver.get("http://watir.com/examples/forms_with_input_elements.html")
elem = driver.find_element_by_id("delete_user_submit")
elem.get_property("style")
any chance that you could see what chromedriver returns as payload for the "Get Element Property" command?
It's an Array of the values, which, again I'm not sure is correct here:
2021-02-22 11:32:52 INFO Selenium <- {"value":["border-top-width","border-right-width","border-bottom-width","border-left-width","border-top-style","border-right-style","border-bottom-style","border-left-style","border-top-color","border-right-color","border-bottom-color","border-left-color","border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"]}
So the object we are talking about here is CSS2Properties.
When having a look at Get Element Property I can see that we directly return the value of the property. This will indeed fail in cases where the object is not serializable, or we get a full list of properties returned (as what Marionette/geckodriver does right now).
To fix that we should reference the serialization of the value here, right?
@jgraham, would be good to get your input here.
Uh, the spec seems to assume all element properties have a trivial serialization. That seems wrong. Pretty sure anything that can return an arbitary JS object should be calling https://w3c.github.io/webdriver/#dfn-json-clone on the value and returning that.
So, I'm getting this same error when I do:
driver.find_element(id: 'upload').property('onchange')
(html: https://github.com/SeleniumHQ/selenium/blob/trunk/common/src/web/formPage.html)
This should definitely be returning null.
@titusfortner is that still an issue with a recent Firefox? We had some changes in the past and I'm not able to actually reproduce any of your mentioned cases. Thanks.
Running the above mentioned testcase with Marionette I can see the following log output:
1685104776265 Marionette DEBUG 3 -> [0,3,"WebDriver:FindElement",{"value":"upload","using":"id"}]
1685104776266 RemoteAgent TRACE WebDriverProcessData actor created for PID 98572
1685104776267 Marionette TRACE [12] MarionetteCommands actor created for window id 4294967298
1685104776271 Marionette DEBUG 3 <- [1,3,null,{"value":{"element-6066-11e4-a52e-4f735466cecf":"4d4b57d3-9ccf-4888-8c5d-ab6446210de1"}}]
1685104776271 Marionette DEBUG 3 -> [0,4,"WebDriver:GetElementProperty",{"id":"4d4b57d3-9ccf-4888-8c5d-ab6446210de1","name":"onchange"}]
1685104776272 Marionette DEBUG 3 <- [1,4,null,{"value":{}}]
So we return an empty object because we don't serialize the properties of the Function.
Uh, the spec seems to assume all element properties have a trivial serialization. That seems wrong. Pretty sure anything that can return an arbitary JS object should be calling https://w3c.github.io/webdriver/#dfn-json-clone on the value and returning that.
Right, and that is basically https://github.com/w3c/webdriver/issues/1412.
Given that the original test case doesn't throw an error anymore I'm going ahead and close this issue.