Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
selector, = parse('e:after')
assert selector.pseudo_element == 'after'
# Pseudo-element is ignored:
assert GenericTranslator().selector_to_xpath(selector, prefix='') == "e"
# Invalid characters in XPath element names
assert xpath(r'di\a0 v') == (
u("*[name() = 'di v']")) # di\xa0v
assert xpath(r'di\[v') == (
"*[name() = 'di[v']")
assert xpath(r'[h\a0 ref]') == (
u("*[attribute::*[name() = 'h ref']]")) # h\xa0ref
assert xpath(r'[h\]ref]') == (
"*[attribute::*[name() = 'h]ref']]")
self.assertRaises(ExpressionError, xpath, u(':fİrst-child'))
self.assertRaises(ExpressionError, xpath, ':first-of-type')
self.assertRaises(ExpressionError, xpath, ':only-of-type')
self.assertRaises(ExpressionError, xpath, ':last-of-type')
self.assertRaises(ExpressionError, xpath, ':nth-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-last-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-child(n-)')
self.assertRaises(ExpressionError, xpath, ':after')
self.assertRaises(ExpressionError, xpath, ':lorem-ipsum')
self.assertRaises(ExpressionError, xpath, ':lorem(ipsum)')
self.assertRaises(ExpressionError, xpath, '::lorem-ipsum')
self.assertRaises(TypeError, GenericTranslator().css_to_xpath, 4)
self.assertRaises(TypeError, GenericTranslator().selector_to_xpath,
'foo')
# Invalid characters in XPath element names
assert xpath(r'di\a0 v') == (
u("*[name() = 'di v']")) # di\xa0v
assert xpath(r'di\[v') == (
"*[name() = 'di[v']")
assert xpath(r'[h\a0 ref]') == (
u("*[attribute::*[name() = 'h ref']]")) # h\xa0ref
assert xpath(r'[h\]ref]') == (
"*[attribute::*[name() = 'h]ref']]")
self.assertRaises(ExpressionError, xpath, u(':fİrst-child'))
self.assertRaises(ExpressionError, xpath, ':first-of-type')
self.assertRaises(ExpressionError, xpath, ':only-of-type')
self.assertRaises(ExpressionError, xpath, ':last-of-type')
self.assertRaises(ExpressionError, xpath, ':nth-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-last-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-child(n-)')
self.assertRaises(ExpressionError, xpath, ':after')
self.assertRaises(ExpressionError, xpath, ':lorem-ipsum')
self.assertRaises(ExpressionError, xpath, ':lorem(ipsum)')
self.assertRaises(ExpressionError, xpath, '::lorem-ipsum')
self.assertRaises(TypeError, GenericTranslator().css_to_xpath, 4)
self.assertRaises(TypeError, GenericTranslator().selector_to_xpath,
'foo')
assert xpath('e ~ f') == (
"e/following-sibling::f")
assert xpath('div#container p') == (
"div[@id = 'container']/descendant-or-self::*/p")
# Invalid characters in XPath element names
assert xpath(r'di\a0 v') == (
u("*[name() = 'di v']")) # di\xa0v
assert xpath(r'di\[v') == (
"*[name() = 'di[v']")
assert xpath(r'[h\a0 ref]') == (
u("*[attribute::*[name() = 'h ref']]")) # h\xa0ref
assert xpath(r'[h\]ref]') == (
"*[attribute::*[name() = 'h]ref']]")
self.assertRaises(ExpressionError, xpath, ':first-of-type')
self.assertRaises(ExpressionError, xpath, ':only-of-type')
self.assertRaises(ExpressionError, xpath, ':last-of-type')
self.assertRaises(ExpressionError, xpath, ':nth-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-last-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-child(n-)')
self.assertRaises(ExpressionError, xpath, ':after')
self.assertRaises(ExpressionError, xpath, ':lorem-ipsum')
self.assertRaises(ExpressionError, xpath, ':lorem(ipsum)')
self.assertRaises(ExpressionError, xpath, '::lorem-ipsum')
self.assertRaises(TypeError, GenericTranslator().css_to_xpath, 4)
self.assertRaises(TypeError, GenericTranslator().selector_to_xpath,
'foo')
assert xpath(r'di\[v') == (
"*[name() = 'di[v']")
assert xpath(r'[h\a0 ref]') == (
u("*[attribute::*[name() = 'h ref']]")) # h\xa0ref
assert xpath(r'[h\]ref]') == (
"*[attribute::*[name() = 'h]ref']]")
self.assertRaises(ExpressionError, xpath, ':first-of-type')
self.assertRaises(ExpressionError, xpath, ':only-of-type')
self.assertRaises(ExpressionError, xpath, ':last-of-type')
self.assertRaises(ExpressionError, xpath, ':nth-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-last-of-type(1)')
self.assertRaises(ExpressionError, xpath, ':nth-child(n-)')
self.assertRaises(ExpressionError, xpath, ':after')
self.assertRaises(ExpressionError, xpath, ':lorem-ipsum')
self.assertRaises(ExpressionError, xpath, ':lorem(ipsum)')
self.assertRaises(ExpressionError, xpath, '::lorem-ipsum')
self.assertRaises(TypeError, GenericTranslator().css_to_xpath, 4)
self.assertRaises(TypeError, GenericTranslator().selector_to_xpath,
'foo')
def xpath_pseudo_element(self, xpath, pseudo_element):
if isinstance(pseudo_element, FunctionalPseudoElement):
method = 'xpath_%s_functional_pseudo_element' % (
pseudo_element.name.replace('-', '_'))
method = _unicode_safe_getattr(self, method, None)
if not method:
raise ExpressionError(
"The functional pseudo-element ::%s() is unknown"
% pseudo_element.name)
xpath = method(xpath, pseudo_element.arguments)
else:
method = 'xpath_%s_simple_pseudo_element' % (
pseudo_element.replace('-', '_'))
method = _unicode_safe_getattr(self, method, None)
if not method:
raise ExpressionError(
"The pseudo-element ::%s is unknown"
% pseudo_element)
xpath = method(xpath)
return xpath
for rule in stylesheet.cssRules:
rules.extend(self.flatten_rule(rule, href, index))
index = index + 1
# XXX had to fix crash about unsortable type, so that's why we only sort by first item of tuple
rules.sort(key=lambda tup: tup[:1])
self.rules = rules
self._styles = {}
class_sel_pat = re.compile(r'\.[a-z]+', re.IGNORECASE)
capital_sel_pat = re.compile(r'h|[A-Z]+')
for _, _, cssdict, text, _ in rules:
fl = ':first-letter' in text
if fl:
text = text.replace(':first-letter', '')
try:
selector = CSSSelector(text)
except (AssertionError, ExpressionError, etree.XPathSyntaxError,
NameError, # thrown on OS X instead of SelectorSyntaxError
SelectorSyntaxError):
continue
try:
matches = selector(tree)
except etree.XPathEvalError:
continue
if not matches:
ntext = capital_sel_pat.sub(lambda m: m.group().lower(), text)
if ntext != text:
logging.warn('Transformed CSS selector' + text + 'to' + ntext)
selector = CSSSelector(ntext)
matches = selector(tree)
if not matches and class_sel_pat.match(text) and text.lower() != text: