【问题标题】:How to refer to a specific element from the list found by css locator如何从 css 定位器找到的列表中引用特定元素
【发布时间】:2013-06-28 17:03:36
【问题描述】:

我的项目正在使用 Robot Framework 和 Selenium2Library 来测试 Web 系统。

我需要使用 css 定位器找到的元素列表中的特定元素。例如,.innerTable>tbody>tr>td 将找到 10 个元素,我将需要这些元素中的第二个元素。在我之前的项目中,我可以执行以下操作来引用所需的元素:

specific_cell = driver.find_elements(By.CSS_SELECTOR, ".innerTable>tbody>tr>td")[1]

意味着它创建了一个元素列表并使用索引我可以选择一个特定的。但是有谁知道我是否可以用 Robot framework + Selenium2Library 做类似的事情?


我试图了解是否有办法只使用 Selenium2Library 关键字来达到结果。显然,现有的关键字是不可能的。

为了实现使用定位器标识的许多特定元素中的一个特定元素的可能性(在最初的问题中,这些元素是由 css 选择器找到的表格单元格),我们需要深入到 Selenium2Library 库并在那里创建新方法。

在 C:\Python27\Lib\site-packages\Selenium2Library\keywords_element.py 中可以添加这样的方法

def return_elements(self, locator):
    """Returns a list of elements identified by a given locator.
    """
    elements = self._element_find(locator, False, True)
    if elements is None:
        raise AssertionError("Could not find element(s) '%s'" % (locator))
    return elements

这将返回一个 Web 元素对象列表,该列表可用于指出特定元素,然后对其执行一些操作。但是,如果您需要诸如单击、获取文本或键入之类的操作,则必须在同一个类中创建其他方法。 好吧,这看起来不是最佳方式,但至少它确实有效。 另一种选择是使用 xpath 并且不用担心上面的编写,但是一旦您对包含大量相似元素的大页面进行成像并在此处添加使用 Internet Explorer 的要求,那么您可能要避免使用 xpath

【问题讨论】:

  • Selenium 2 webdriver。您应该能够使用这个确切的代码 sn-p 获取有问题的元素。你试过什么?

标签: python webdriver robotframework


【解决方案1】:

如果您没有定位前面有许多兄弟元素的元素,则可以使用相邻兄弟选择器。 例如,以下定位器选择有序列表中的第二项:

css= ol > li:first-child + li

您可能会考虑创建的一个关键字是将 Id 分配给第 N 个元素。 除了将 ID 分配给使用给定定位器返回的元素集合中的第 N 个元素之外,它与将 ID 分配给元素相同。 这将允许您使用其他关键字而不修改 Selenium2Library。 例如:

Assign Id To Nth Element    css= ol > li    27th_item    27
Element Text Should Be    id= 27th_item    some text

这将使选择一个有许多兄弟姐妹的孩子更容易。 对于相邻的兄弟选择器,在这种情况下选择器会很大,因为 nth-child 直到 CSS3 才可用。

这是将 Id 分配给第 N 个元素的实现:

from robot.libraries.BuiltIn import BuiltIn


class S2LExt(object):

    def assign_id_to_nth_element(self, locator, id, n):
        """Assigns a temporary identifier to the Nth element found.

        This is mainly useful if the locator is complicated/slow XPath expression.
        Identifier expires when the page is reloaded. `n` is 1-based index of the
        element in the set found with the given `locator` to assign an ID to.

        Example:
        | Assign ID to Nth Element | xpath=//div[@id="first_div"] | my id | 5 |
        | Page Should Contain Element | my id |
        """
        lib = BuiltIn().get_library_instance('Selenium2Library')
        n = int(n)
        elements = lib._element_find(locator, False, True)
        if len(elements) < n:
            raise IndexError("Only %d elements found using locator '%s'." % (len(elements), locator))
        lib._info("Assigning temporary id '%s' to element '%s'" % (id, locator))
        lib._current_browser().execute_script("arguments[0].id = '%s';" % id, elements[n-1])

【讨论】:

    【解决方案2】:

    我总是建议不要抓住一个微小的元素并给它一个名字。创建一个更大的元素主体,让那些使用你的元素的人定义他们想要的。

    class TablePage(object):
        """A page with a table on it."""
    
        def __init__(self):            
            # I would call super() on the `BasePage` here.
            pass
    
        @property
        def table_element(self):
            # factored out: '.innerTable td'
            css = '.innerTable > tbody > tr > td'
            return self.driver.find_elements(By.CSS_SELECTOR, css)
    
        def find_in_table_element(self, table_text):
            for entry in self.table_element:
                # you may want case-sensitive here
                if entry.text.lower == table_text.lower
                return entry
            return [] #  or None...
    

    您可以在这里更流畅地使用它,依靠您的应用程序代码来完成实际工作,并希望为您减少维护工作。网页一直在变化!

    你可以这样实现它:

    page_with_table = TablePage()
    second_entry = page_with_table.table_element[1]
    table_entry_by_text = page_with_table.find_in_table_element('specific text')
    assertEquals(second_entry.text, table_entry_by_text.text) #  or whatever
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 2019-11-15
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      相关资源
      最近更新 更多