dash-labs icon indicating copy to clipboard operation
dash-labs copied to clipboard

build_id creates IDs that are extremely hard to use with selenium

Open asford opened this issue 4 years ago • 1 comments

The current dynamic id implementation is fantastic, but is very hard to use with the selenium selectors used in dash.testing. In "normal" dash, we expect component ids to be str values which are directly mapped to a component id. This allows you to use dash_duo.driver.find_element_by_id to select page element corresponding to dash components.

However, the dynamic ids created by build_id are dictionaries which are string-serialized into component ids. I believe occurs in the dash frontend at: https://github.com/plotly/dash/blob/7afb2edbccff0af98f87df083dd6fbedece10463/dash/dash-renderer/src/actions/dependencies.js#L114-L123

This means that:

a) The css component ID, for use in selectors, isn't easily derived from the python component's .id property as it depends on the dict's serialization format. b) The serialized dict requires CSS identifier escaping to be used in selenium selectors.

This breaks the existing dash_duo.driver.find_element_by_id and dash_duo.wait_for_element_by_id interfaces.

Neither of these are insurmountable, but it would be preferable if there was a "simple" way of accessing the "css-selector-id" of the component id.

Potential options could include:

a) Returning a canonical string id from build_id. b) Implementing an equivalent to the existing stringifyID function in python, so that it can be applied to python identifiers.

Either case will require CSS selector escaping for any special characters, which could be handled via soupsieve.escape.

asford avatar Jun 29 '21 17:06 asford

+1. We have faced the same issue (https://github.com/plotly/dash/issues/1625). It turned out that for a) a public Python serialization function already exists, though not at the top package level (and undocumented as well, so I guess as close to private function as it gets without _ prepended).

Regarding b) I didn't know about soupsieve :+1: In our Dash based project we currently use these lines. Ideally I guess selenium itself should support CSS escaping strings, I was a bit surprised I couldn't find a utility function there (maybe worth a PR towards selenium as well :thinking:).

In my view I think dash.testing also supporting something like this would be nice + easy (and not too magical since we are in dash ID context): https://github.com/plotly/dash/pull/1637#discussion_r628930562

anders-kiaer avatar Jun 29 '21 18:06 anders-kiaer