def test_uses_substring_matching_otherwise(self): xpath1 = to_xpath(x.descendant("div")[x.attr("id").is_("foo")]) results = self.find_all(xpath1) self.assertEqual(results[0].get("title"), "fooDiv") xpath2 = to_xpath(x.descendant("div")[x.attr("id").is_("oo")]) results = self.find_all(xpath2) self.assertEqual(results[0].get("title"), "fooDiv")
def test_uses_equality_when_exact_given(self): xpath1 = to_xpath(descendant("div")[attr("id").is_("foo")], exact=True) results = self.find_all(xpath1) self.assertEqual(results[0].get_attribute("title"), "fooDiv") xpath2 = to_xpath(descendant("div")[attr("id").is_("oo")], exact=True) results = self.find_all(xpath2) self.assertSequenceEqual(results, [])
def test_selects_a_nodes_text(self): xpath = to_xpath(x.descendant("p")[x.text == "Bax"]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Bax") self.assertEqual(results[1].get("title"), "monkey") xpath = to_xpath(x.descendant("div")[x.descendant("p").text == "Bax"]) results = self.find_all(xpath) self.assertEqual(results[0].get("title"), "fooDiv")
def test_matches_quotes(self): locator = "Who's quotes? \"Their\" quotes." xpath = to_xpath(x.descendant("div")[x.string.n.is_(locator)]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "quotes") xpath = to_xpath(x.descendant("div")[x.attr("title") == locator]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "quotes")
def test_matches_encoded_unicode_characters(self): locator = "이름".encode("UTF-8") if sys.version_info >= (3, 0) else "이름" xpath = to_xpath(x.descendant("div")[x.string.n.is_(locator)]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "unicode") xpath = to_xpath(x.descendant("div")[x.attr("title") == locator]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "unicode")
def test_matches_decoded_unicode_characters(self): locator = "이름" if sys.version_info >= (3, 0) else u"이름" xpath = to_xpath(x.descendant("div")[x.string.n.is_(locator)]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "unicode") xpath = to_xpath(x.descendant("div")[x.attr("title") == locator]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "unicode")
def test_matches_encoded_unicode_characters(self): locator = "이름".encode("UTF-8") if sys.version_info >= (3, 0) else "이름" xpath = to_xpath(descendant("div")[string.n.is_(locator)]) results = self.find_all(xpath) self.assertEqual(results[0].get_attribute("id"), "unicode") xpath = to_xpath(descendant("div")[attr("title") == locator]) results = self.find_all(xpath) self.assertEqual(results[0].get_attribute("id"), "unicode")
def test_matches_quotes(self): locator = "Who's quotes? \"Their\" quotes." xpath = to_xpath(descendant("div")[string.n.is_(locator)]) results = self.find_all(xpath) self.assertEqual(results[0].get_attribute("id"), "quotes") xpath = to_xpath(descendant("div")[attr("title") == locator]) results = self.find_all(xpath) self.assertEqual(results[0].get_attribute("id"), "quotes")
def test_creates_a_union_expression(self): expr1 = x.descendant("p") expr2 = x.descendant("div") collection = expr1.union(expr2) xpath1 = to_xpath(collection.where(x.attr("id").equals("union-item-3"))) xpath2 = to_xpath(collection.where(x.attr("id").equals("union-item-4"))) results = self.find_all(xpath1) self.assertEqual(results[0].text, "Cherry") results = self.find_all(xpath2) self.assertEqual(results[0].text, "Date")
def test_where_aliased_as_square_brackets(self): expr1 = x.descendant("p") expr2 = x.descendant("div") collection = expr1.union(expr2) xpath1 = to_xpath(collection[x.attr("id").equals("union-item-3")]) xpath2 = to_xpath(collection[x.attr("id").equals("union-item-4")]) results = self.find_all(xpath1) self.assertEqual(results[0].text, "Cherry") results = self.find_all(xpath2) self.assertEqual(results[0].text, "Date")
def test_aliased_as_plus_sign(self): expr1 = x.descendant("p") expr2 = x.descendant("div") collection = expr1 + expr2 xpath1 = to_xpath(collection.where(x.attr("id").equals("union-item-3"))) xpath2 = to_xpath(collection.where(x.attr("id").equals("union-item-4"))) results = self.find_all(xpath1) self.assertEqual(results[0].text, "Cherry") results = self.find_all(xpath2) self.assertEqual(results[0].text, "Date")
def test_finds_multiple_kinds_of_nodes_regardless_of_the_context(self): xpath = to_xpath(x.descendant("div")[x.attr("id") == "woo"].anywhere("p", "ul")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Blah") self.assertEqual(inner_text(results[3]), "A list") self.assertEqual(inner_text(results[4]), "A list") self.assertEqual(inner_text(results[6]), "Bax")
def test_allows_comma_separated_selectors(self): xpath = to_xpath( x.descendant()[x.attr("id").equals("moar")].css("div, p")) results = self.find_all(xpath) self.assertEqual(results[0].text, "chimp") self.assertEqual(results[1].text, "elephant") self.assertEqual(results[2].text, "flamingo")
def params(self, button): params = MultiDict() types = ["input", "select", "textarea"] xpath = x.descendant(*types)[~x.attr("form")] if self.native.get("id"): xpath += x.anywhere( *types)[x.attr("form") == self.native.get("id")] xpath = xpath[~x.attr("disabled")] for field in self._find_xpath(to_xpath(xpath)): if field.tag_name == "input": if field["type"] in ["checkbox", "radio"]: if field.checked: params.add(field["name"], field.value) elif field["type"] == "file": if self._multipart: if field.value: params.add( field["name"], FileStorage(stream=open(field.value, "rb"), filename=os.path.basename( field.value))) else: params.add( field["name"], FileStorage( stream=BytesIO(), content_type="application/octet-stream")) else: if field.value: params.add(field["name"], os.path.basename(field.value)) elif field["type"] in ["submit", "reset", "image"]: pass else: params.add(field["name"], field.value) elif field.tag_name == "textarea": if field.value: params.add(field["name"], re.sub("\n", "\r\n", field.value)) elif field.tag_name == "select": if field["multiple"] == "multiple": options = field.native.xpath( ".//option[@selected='selected']") for option in options: params.add(field["name"], option.get("value", option.text)) else: options = field.native.xpath( ".//option[@selected='selected']") if not len(options): options = field.native.xpath(".//option") if len(options): params.add(field["name"], options[0].get("value", options[0].text)) params.add(button["name"], button["value"] or "") return params
def _set_radio(self, value): other_radios = self.native.xpath(to_xpath( x.anywhere("input")[x.attr("name") == self["name"]])) for node in other_radios: node.attrib.pop("checked", None) self.native.set("checked", "checked")
def test_calls_the_given_xpath_function_with_the_current_node_as_the_first_argument( self): xpath = to_xpath( x.descendant("span").where( x.attr("id") == "string-length").text.method("string-length")) results = self.find_all(xpath) self.assertEquals(results, 11)
def resolve(): match_result = super(type(self), self).resolve_for( node.session.current_scope, exact=exact) return node.find_all( "xpath", to_xpath(x.preceding_sibling().union(x.following_sibling())), filter=lambda el: el in match_result)
def test_finds_all_nodes_in_either_expression(self): xpath = to_xpath( descendant("*")[attr("id").equals("foo").or_( attr("id").equals("fooDiv"))]) results = self.find_all(xpath) self.assertEqual(results[0].get_attribute("title"), "fooDiv") self.assertEqual(results[1].text, "Blah")
def test_checks_greater_than_or_equal(self): xpath = to_xpath(x.descendant("p")[x.position().gte(2)]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Bax") self.assertEqual(results[1].get("title"), "monkey") self.assertEqual(results[2].text, "Bax") self.assertEqual(results[3].text, "Blah")
def test_used_as_an_expression(self): parent = x.descendant("div")[x.attr("id").equals("union")] expr1 = x.descendant("p") expr2 = x.descendant("div") collection = expr1.union(expr2) xpath1 = to_xpath(parent.descendant(collection[x.attr("id").equals("union-item-3")])) xpath2 = to_xpath(parent.descendant(collection[x.attr("id").equals("union-item-4")])) results = self.find_all(xpath1) self.assertEqual(results[0].text, "Cherry") results = self.find_all(xpath2) self.assertEqual(results[0].text, "Date")
def test_aliased_as_right_angle_bracket_equals(self): xpath = to_xpath(x.descendant("p")[x.position() >= 2]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Bax") self.assertEqual(results[1].get("title"), "monkey") self.assertEqual(results[2].text, "Bax") self.assertEqual(results[3].text, "Blah")
def test_aliased_as_pipe(self): xpath = to_xpath( descendant("*")[attr("id").equals("foo") | attr("id").equals("fooDiv")]) results = self.find_all(xpath) self.assertEqual(results[0].get_attribute("title"), "fooDiv") self.assertEqual(results[1].text, "Blah")
def resolve(): match_result = super(type(self), self).resolve_for(node.session.current_scope, exact=exact) return node.find_all("xpath", to_xpath(x.ancestor()), filter=lambda el: el in match_result)
def test_finds_all_nodes_when_no_arguments_given_regardless_of_the_context(self): xpath = to_xpath(x.descendant("div")[x.attr("id") == "woo"].anywhere()) results = self.find_all(xpath) self.assertEqual(results[0].tag, "html") self.assertEqual(results[1].tag, "head") self.assertEqual(results[3].tag, "body") self.assertEqual(inner_text(results[5]), "Blah") self.assertEqual(inner_text(results[9]), "A list") self.assertEqual(inner_text(results[12]), "A list") self.assertEqual(inner_text(results[14]), "Bax")
def test_creates_a_second_order_union(self): expr1 = x.descendant("p") expr2 = x.descendant("div") expr3 = x.descendant("span") collection1 = expr1.union(expr2)[x.attr("id") == "union-item-5"] collection2 = collection1.union(expr3[x.attr("id") == "union-item-6"]) xpath = to_xpath(collection2) results = self.find_all(xpath) self.assertEqual(results[0].text, "Fig")
def test_second_order_union_aliased_as_plus_sign(self): expr1 = x.descendant("p") expr2 = x.descendant("div") expr3 = x.descendant("span") collection1 = (expr1 + expr2)[x.attr("id") == "union-item-5"] collection2 = collection1 + expr3[x.attr("id") == "union-item-6"] xpath = to_xpath(collection2) results = self.find_all(xpath) self.assertEqual(results[0].text, "Fig")
def test_finds_nodes_which_are_exactly_preceding_the_current_node(self): woo_div = x.descendant("p")[x.attr("id").equals("wooDiv")] gorilla = x.descendant("p")[x.attr("title").equals("gorilla")] xpath = to_xpath(woo_div.previous_sibling("p")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Bax") xpath = to_xpath(woo_div.previous_sibling("ul", "p")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Bax") xpath = to_xpath(gorilla.previous_sibling("ul", "p")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "A list") xpath = to_xpath(woo_div.previous_sibling("ul", "li")) results = self.find_all(xpath) self.assertSequenceEqual(results, []) xpath = to_xpath(woo_div.previous_sibling()) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Bax")
def test_finds_nodes_which_are_immediate_siblings_of_the_current_node(self): foo_div = x.descendant("p")[x.attr("id").equals("fooDiv")] monkey = x.descendant("p")[x.attr("title").equals("monkey")] xpath = to_xpath(foo_div.next_sibling("p")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Bax") xpath = to_xpath(foo_div.next_sibling("ul", "p")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Bax") xpath = to_xpath(monkey.next_sibling("ul", "p")) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "A list") xpath = to_xpath(foo_div.next_sibling("ul", "li")) results = self.find_all(xpath) self.assertSequenceEqual(results, []) xpath = to_xpath(foo_div.next_sibling()) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Bax")
def xpath(self, exact=None): """ Returns the XPath query for this selector. Args: exact (bool, optional): Whether to exactly match text. Returns: str: The XPath query for this selector. """ exact = exact if exact is not None else self.exact if isinstance(self.expression, ExpressionType): return to_xpath(self.expression, exact=exact) else: return str(self.expression)
def xpath(self, exact=None): """ Returns the XPath query for this selector. Args: exact (bool, optional): Whether to exactly match text. Returns: str: The XPath query for this selector. """ exact = exact if exact is not None else self.exact if isinstance(self.expression, AbstractExpression): expression = self._apply_expression_filters(self.expression) return to_xpath(expression, exact=exact) else: return str_(self.expression)
def get(self, locator, exact=False): """ Returns the ``data`` attribute of the first element matching the locator, if any. Args: locator (str): A string that identifies the desired element. Returns: str | None: The ``data`` attribute of the first matching element, if any. """ # Determine the :mod:`xpath.html` matcher. matcher_name = getattr(type(self), "__matcher__") matcher = getattr(html, matcher_name) # Find all matching elements. expression = matcher(locator) xpath = to_xpath(expression, exact=exact) elements = self.document.xpath(xpath) return elements[0].get("data") if len(elements) else None
def test_divides(self): xpath = to_xpath(x.descendant("p")[x.position().divide(2) == 1]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Bax") self.assertEqual(results[1].text, "Bax")
def test_calls_the_given_xpath_function(self): xpath = to_xpath(x.function("boolean", x.function("true") == x.function("false"))) results = self.find_all(xpath) self.assertIs(results, False)
def test_finds_all_nodes_in_both_expressions(self): xpath = to_xpath(x.descendant("*")[x.contains("Bax").and_(x.attr("title").equals("monkey"))]) results = self.find_all(xpath) self.assertEqual(results[0].get("title"), "monkey")
def test_aliased_as_ampersand(self): xpath = to_xpath(x.descendant("*")[x.contains("Bax") & x.attr("title").equals("monkey")]) results = self.find_all(xpath) self.assertEqual(results[0].get("title"), "monkey")
def test_returns_the_length_of_a_string(self): xpath = to_xpath(x.descendant("span")[x.text.string_length == 11]) results = self.find_all(xpath) self.assertEqual(results[1].get("id"), "string-length")
def test_takes_modulo(self): xpath = to_xpath(x.descendant("p")[x.position().mod(2) == 1]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Blah") self.assertEqual(results[1].get("title"), "monkey") self.assertEqual(results[2].get("title"), "gorilla")
def test_selects_the_part_of_a_string_after_the_specified_character(self): xpath = to_xpath(x.descendant("*")[x.text.substring(7).equals("there")]) results = self.find_all(xpath) self.assertEquals(results[0].get("id"), "substring")
def test_aliased_as_left_angle_bracket(self): xpath = to_xpath(x.descendant("p")[x.position() < 2]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Blah") self.assertEqual(results[1].get("title"), "gorilla")
def test_finds_nodes_that_begin_with_the_given_string(self): xpath = to_xpath(x.descendant("*")[x.attr("id").starts_with("foo")]) results = self.find_all(xpath) self.assertEqual(len(results), 2) self.assertEqual(results[0].get("id"), "foo") self.assertEqual(results[1].get("id"), "fooDiv")
def test_selects_the_part_of_a_string_after_the_specified_character_and_up_to_the_given_length(self): xpath = to_xpath(x.descendant("*")[x.text.substring(2, 4).equals("ello")]) results = self.find_all(xpath) self.assertEquals(results[0].get("id"), "substring")
def test_finds_nodes_that_contain_the_given_expression(self): expr = x.anywhere("div")[x.attr("title") == "fooDiv"].attr("id") xpath = to_xpath(x.descendant("div")[x.attr("title").starts_with(expr)]) results = self.find_all(xpath) self.assertEqual(results[0].get("id"), "foo")
def test_counts_the_number_of_occurrences(self): xpath = to_xpath(x.descendant("div")[x.descendant("p").count == 2]) results = self.find_all(xpath) self.assertEquals(results[0].get("id"), "preference")
def test_checks_lesser_than(self): xpath = to_xpath(x.descendant("p")[x.position().lt(2)]) results = self.find_all(xpath) self.assertEqual(results[0].text, "Blah") self.assertEqual(results[1].get("title"), "gorilla")
def test_finds_nodes_regardless_of_the_context(self): foo_div = x.anywhere("div")[x.attr("id").equals("foo")] xpath = to_xpath(x.descendant("p")[x.attr("id").equals(foo_div.attr("title"))]) results = self.find_all(xpath) self.assertEqual(inner_text(results[0]), "Blah")
def test_matches_all_nodes_where_the_condition_matches(self): xpath = to_xpath(x.descendant("*")[x.attr("id").one_of("foo", "baz")]) results = self.find_all(xpath) self.assertEqual(results[0].get("title"), "fooDiv") self.assertEqual(results[1].get("title"), "bazDiv")
def test_matches_only_when_not_equal(self): xpath = to_xpath(x.descendant("div")[x.attr("id").not_equals("bar")]) results = self.find_all(xpath) self.assertEqual(results[0].get("title"), "fooDiv")
def test_finds_nodes_by_the_given_css_selector(self): xpath = to_xpath(x.css("#preference p")) results = self.find_all(xpath) self.assertEqual(results[0].text, "allamas") self.assertEqual(results[1].text, "llama")