Fix CSS selector support for numeric IDs and escape sequences#150
Fix CSS selector support for numeric IDs and escape sequences#150sinpru wants to merge 1 commit intoFlaUI:mainfrom
Conversation
|
|
||
| private (string strategy, string value) ParseCssSelector(string cssSelector) | ||
| { | ||
| if (cssSelector.StartsWith("#")) |
There was a problem hiding this comment.
This is not sufficient to judge that it is a simple CSS ID selector. To be sure, shouldn't a regex be used that checks that the complete cssSelector string matches a simple ID selector? It may be that the user sends a compound selector instead, and we should have a proper error message in that case that this is not supported.
The same comment holds for all parses below. To check that a regex matches the string fully, start with ^ and end with $.
|
Would it be possible to add a unit test to e.g. |
|
Actually I found out that my approach to fixing the CSS selector inside the controller was a mistake. I've refactored this to handle CSS selector parsing in ConditionParser instead. |
| } | ||
|
|
||
| var nameMatch = Regex.Match(cssSelector, @"\*?\[name\s*=\s*""(.+?)""\]", RegexOptions.IgnoreCase); | ||
| var nameMatch = Regex.Match(cssSelector, @"^\*?\[name\s*=\s*""(.+?)""\]$", RegexOptions.IgnoreCase); |
There was a problem hiding this comment.
Couldn't this still match [name="test"][class="test2"] because of the .+ expression? If so, I suggest [^""]+ instead. Please add a unit test to validate that [name="test"][class="test2"] throws as not supported.
There was a problem hiding this comment.
You're right, the .+ is too greedy, I've added a unit test that validates compound selectors throws as intened.
| { | ||
| element = await Wait.Until(() => startNode().FindFirstByXPath(findElementRequest.Value), element => element != null, session.ImplicitWaitTimeout); | ||
| } | ||
| else if (findElementRequest.Using == "css selector") |
There was a problem hiding this comment.
I've had a closer look and it seems that the ConditionParser should already allow escaped characters too. Instead of adding another case here, can't we fix the ConditionParser regular expressions if they fail?
| @@ -31,19 +29,24 @@ public class ConditionParser : IConditionParser | |||
| /// - Attribute equals attribute (e.g. `[name=value]`) not supported. | |||
There was a problem hiding this comment.
Also update the comment above Unicode escape characters or escape characters in the attribute name are not supported. -> Escape characters in the attribute name are not supported.
| /// - Multiple selectors are not supported. | ||
| /// </summary> | ||
| private static Regex SimpleCssIdSelectorRegex = new Regex(@"^#(?<name>(?<nmchar>[_a-z0-9-]|[\240-\377]|(?<escape>\\[^\r\n\f0-9a-f]))+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); | ||
| private static Regex SimpleCssIdSelectorRegex = new Regex(@"^#(?<name>(?<nmchar>[_a-z0-9-]|[\240-\377]|(?<escape>\\[^\r\n\f0-9a-f])|(?<unicode>\\[0-9a-fA-F]{1,6}\s?))+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
There was a problem hiding this comment.
Shouldn't the \s? part be omitted here?
There was a problem hiding this comment.
The \s? is needed to make the trailing space optional per CSS spec. Unicode escapes like \34 can be followed by an optional space (\34 b or \34b are both valid depending on context).
| /// - Multiple selectors are not supported. | ||
| /// </summary> | ||
| private static Regex SimpleCssClassSelectorRegex = new Regex(@"^\.(?<ident>-?(?<nmstart>[_a-z]|[\240-\377])(?<nmchar>[_a-z0-9-]|[\240-\377]|(?<escape>\\[^\r\n\f0-9a-f]))*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); | ||
| private static Regex SimpleCssClassSelectorRegex = new Regex(@"^\.(?<ident>-?(?<nmstart>[_a-z]|[\240-\377])(?<nmchar>[_a-z0-9-]|[\240-\377]|(?<escape>\\[^\r\n\f0-9a-f])|(?<unicode>\\[0-9a-fA-F]{1,6}\s?))*)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
There was a problem hiding this comment.
Shouldn't the \s? part be omitted here?
There was a problem hiding this comment.
This goes the same as the one above
| /// - ~= or |= not supported. | ||
| /// </summary> | ||
| private static Regex SimpleCssAttributeSelectorRegex = new Regex(@"^\*?\[\s*(?<ident>-?(?<nmstart>[_a-z]|[\240-\377])(?<nmchar>[_a-z0-9-]|[\240-\377])*)\s*=\s*(?<string>(?<string1>""(?<string1value>([^\n\r\f\\""]|(?<escape>\\[^\r\n\f0-9a-f]))*)"")|(?<string2>'(?<string2value>([^\n\r\f\\']|(?<escape>\\[^\r\n\f0-9a-f]))*)'))\s*\]$", RegexOptions.Compiled | RegexOptions.IgnoreCase); | ||
| private static Regex SimpleCssAttributeSelectorRegex = new Regex(@"^\*?\[\s*(?<ident>-?(?<nmstart>[_a-z]|[\240-\377])(?<nmchar>[_a-z0-9-]|[\240-\377])*)\s*=\s*(?<string>(?<string1>""(?<string1value>([^\n\r\f\\""]|(?<escape>\\[^\r\n\f0-9a-f])|(?<unicode>\\[0-9a-fA-F]{1,6}\s?))*)"")|(?<string2>'(?<string2value>([^\n\r\f\\']|(?<escape>\\[^\r\n\f0-9a-f])|(?<unicode>\\[0-9a-fA-F]{1,6}\s?))*)'))\s*\]$", RegexOptions.Compiled | RegexOptions.IgnoreCase); |
There was a problem hiding this comment.
Shouldn't the \s? part be omitted here?
| [Test] | ||
| public void ParseCondition_CssSelectorWithSimpleNumericId_ReturnsAutomationIdCondition() | ||
| { | ||
| var cssSelector = @"#\31 "; |
There was a problem hiding this comment.
Isn't "#\31" without the trailing space a better example for this case?
There was a problem hiding this comment.
The trailing space is needed when the next character is a hex digit. Without it #\31b would be parsed as a 3-character escape (\31b) instead of \31 followed by b.
| { | ||
| public class ConditionParserTests | ||
| { | ||
| [TestCase("[name=\"2\"]")] |
There was a problem hiding this comment.
Why were the ParseCondition_ByCssAttributeName_ReturnsCondition test cases removed?
There was a problem hiding this comment.
The old test was removed because it was testing the same functionality now covered by ParseCondition_CssSelectorWithEscapedSpecialChars_ReturnsNameCondition. Should I keep both for coverage?
|
Please squash the commits in this merge request together. E.g. with |
bbc21dd to
81ad120
Compare
Fixes #138