Thanks David
Bit of a background to this....:-)
The UI endpoints of the AUT's have zero DfT (Design for Test) built in and getting the teams (well, managers :-)) to get the required test hooks and handles in - and maintain them - would be akin to beating my head against a proverbial brick wall. In addition, the test team while being great testers are very non-technical. The AUT's are highly cross-platform and the UI's render on IE8/9/10/11, Chrome, iPhone's, iPad's and Android (Chrome again) devices. So that is canvas I've got for building the framework - they have done the usual record-playback route and currently realising it doesn't deliver.
The framework is based on use of an Action/Keyword hybrid system using Selenium to drive the UI endpoint. The AUT's all use in-house devved UI controls (grids, dropdowns, textboxes et al....) which can be highly nested etc. So, the framework is based on function oriented Object Maps that contain the control page related find-logic. The Controls are controlled by libraries with their own internal mapping to their elements other Controls etc. This enables the framework to run against any of the targeted UI endpoints as any 'custom' control actions (IE. Appium left/right swipe or scroll is a bit iffy at the moment so I've used some Javascript to workaround that issue; when fixed I can just take the 'hack' out of the library and tests wont be affected). Therefore the Find-Logic is very parent-child oriented; there is find logic to the top-level control, then the child control is located and so on. While is sounds complex, it is actually very simple and produces pretty rock solid and robust tests that the non-techy testers can write/maintain (Databases, Filedrops and SMTP are the other test endpoints).
I had been using XPath as the find logic as it worked cross-browser/device and, even v1.0, able to handle any of the find-logic needed. However, I had an issue with some find-logic not working in IE9 and during digging found that XPath under IE is a bit of a Selenium weak-point (3rd party old XPath interpreter etc...). I've been hearing the loud noises from the CSS Selector advocates and after reading the arguments for/against CSSS decided to move to CSSS. I'd sorted out CSSS's descending predicate issue (where you can select an element based on something to do with its children/descendants) with a recursive filter-loop but this one looks like it could be a job-stopper that forces me back to XPath.
The example is a very simplified view of the issue. In wordy speak, I want to be able to select a child element under an already identified element. In XPath, something like this...
X = driver.FindElement(By.XPath("//div[attirb='xyz']");
Y = X.FindElement(By.XPath("/div[attrib='abc']");
Where the actual find logic is irrelevant, In the second line I really just want the FindElement to apply the find logic from the 'X' element - so in that case the 'DOM root element is the 'X' element and the find-logic is being applied from that point. In CSS Selector world I would expect to be able to say (neither works);
X = driver.FindElement(By.CssSelector("div[attrib=xyz]");
Y = X.FindElements(By.CssSelector(":root>div[attrib=abc]");
or
Y = X.FindElements(By.CssSelector(">div[attrib=abc]");
In the first instance, the ':root' is the 'X' element, so FindElements returns only the child div's that have an attrib atribute containing 'abc'.
In the second instance, there is nothing before the '>' and so it is implied that we are looking for a child div under the current element.
I spent most of last night trying various ways but have come to the conclusion that it really is not possible with CSS Selectors to do this. There are workarounds like remembering the find-logic for each node down the tree or mixing XPath and CSS but they are not really robust and add quite a bit of complexity (Breaking the 'KISS' law - Keep It Simple Stupid :-)).
The thing that mildly confuses me is that the javascript 'querySelectorAll()' method does look - reading the w3c - to be exactly what is needed; "querySelectorAll() method returns a collection of an element's child elements that match a specified CSS selector(s)." So what does the Selenium driver use for <IWebElement>.FindElements(ByCssSelector) as it returns the descendants that match the selector NOT just the child elements'? If I have a selector "div[attrib=xyz" it returns all the element's descendants that match, not just the child elements... I've not actually tried it yet to see if 'child' really does means the direct children of the element or really means 'descendants'....