# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: # Copyright 2014-2015 Florian Bruhin (The Compiler) # # This file is part of qutebrowser. # # qutebrowser is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # qutebrowser is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with qutebrowser. If not, see . # pylint: disable=protected-access """Tests for the webelement utils.""" from unittest import mock import collections.abc import operator import itertools import hypothesis import hypothesis.strategies from PyQt5.QtCore import QRect, QPoint from PyQt5.QtWebKit import QWebElement import pytest from qutebrowser.browser import webelem def get_webelem(geometry=None, frame=None, null=False, style=None, display='', attributes=None, tagname=None, classes=None): """Factory for WebElementWrapper objects based on a mock. Args: geometry: The geometry of the QWebElement as QRect. frame: The QWebFrame the element is in. null: Whether the element is null or not. style: A dict with the styleAttributes of the element. attributes: Boolean HTML attributes to be added. tagname: The tag name. classes: HTML classes to be added. """ elem = mock.Mock() elem.isNull.return_value = null elem.geometry.return_value = geometry elem.webFrame.return_value = frame elem.tagName.return_value = tagname elem.toOuterXml.return_value = '' elem.toPlainText.return_value = 'text' attribute_dict = {} if attributes is None: pass elif not isinstance(attributes, collections.abc.Mapping): attribute_dict.update({e: None for e in attributes}) else: attribute_dict.update(attributes) elem.hasAttribute.side_effect = lambda k: k in attribute_dict elem.attribute.side_effect = lambda k: attribute_dict.get(k, '') elem.setAttribute.side_effect = (lambda k, v: operator.setitem(attribute_dict, k, v)) elem.removeAttribute.side_effect = attribute_dict.pop elem.attributeNames.return_value = list(attribute_dict) if classes is not None: elem.classes.return_value = classes.split(' ') else: elem.classes.return_value = [] style_dict = {'visibility': '', 'display': ''} if style is not None: style_dict.update(style) def _style_property(name, strategy): """Helper function to act as styleProperty method.""" if strategy != QWebElement.ComputedStyle: raise ValueError("styleProperty called with strategy != " "ComputedStyle ({})!".format(strategy)) return style_dict[name] elem.styleProperty.side_effect = _style_property wrapped = webelem.WebElementWrapper(elem) return wrapped class SelectionAndFilterTests: """Generator for tests for TestSelectionsAndFilters.""" # A mapping of a HTML element to a list of groups where the selectors # (after filtering) should match. # # Based on this, test cases are generated to make sure it matches those # groups and not the others. TESTS = [ ('', []), ('', []), ('', [webelem.Group.url]), ('', [webelem.Group.url]), ('', [webelem.Group.all]), ('', [webelem.Group.all, webelem.Group.links, webelem.Group.prevnext, webelem.Group.url]), ('', [webelem.Group.all, webelem.Group.url]), ('', [webelem.Group.all]), ('', [webelem.Group.all, webelem.Group.links, webelem.Group.prevnext, webelem.Group.url]), ('', [webelem.Group.all, webelem.Group.url]), ('', [webelem.Group.all]), ('', [webelem.Group.all, webelem.Group.links, webelem.Group.prevnext, webelem.Group.url]), ('', [webelem.Group.all, webelem.Group.url]), ('