geckodriver icon indicating copy to clipboard operation
geckodriver copied to clipboard

Getting element property for invalid property throws error

Open titusfortner opened this issue 4 years ago • 9 comments

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"]}

titusfortner avatar Feb 22 '21 17:02 titusfortner

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')?

whimboo avatar Feb 22 '21 19:02 whimboo

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.

whimboo avatar Feb 22 '21 19:02 whimboo

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":""}}

titusfortner avatar Feb 22 '21 20:02 titusfortner

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 avatar Feb 22 '21 20:02 titusfortner

@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")

whimboo avatar Feb 23 '21 21:02 whimboo

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"]}

titusfortner avatar Feb 24 '21 04:02 titusfortner

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.

whimboo avatar Feb 24 '21 07:02 whimboo

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.

jgraham avatar Feb 25 '21 12:02 jgraham

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 avatar Feb 27 '21 19:02 titusfortner

@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.

whimboo avatar May 09 '23 15:05 whimboo

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.

whimboo avatar May 26 '23 13:05 whimboo

Given that the original test case doesn't throw an error anymore I'm going ahead and close this issue.

whimboo avatar May 26 '23 13:05 whimboo