Robot Framework和Xpath - 使用条件选择元素

时间:2017-04-05 15:45:00

标签: xpath robotframework

新人在这里。我是第一次进入自动化测试,我测试的网站使用AngularJS生成动态图形和条形图,其中包含不断变化的数据和div ID。由于我不熟悉代码,我希望使用Robot Framework和相对Xpath来组合测试脚本。我对Xpath的了解主要源于W3学校的Xpath教程(https://www.w3schools.com/xml/xpath_syntax.asp

以下是我目前正在测试的页面部分的基本框架:

<html>
    <body>
        <div class="charts_and_graphs">
            <div class="bar_chart">
                <h1>Book Sales</h1>
                <div class="key_area"></div>
                <div class="bar_area">
                    <div class="bar">a1</div>
                    <div class="bar">a2</div>
                    <div class="bar">a3</div>
                </div>
                <h1>Pen Sales</h1>
                <div class="key_area"></div>
                <div class="bar_area">
                    <div class="bar">b1</div>
                    <div class="bar">b2</div>
                    <div class="bar">b3</div>
                </div>
                <h1>Bag Sales</h1>
                <div class="key_area"></div>
                <div class="bar_area">
                    <div class="bar">c1</div>
                    <div class="bar">c2</div>
                    <div class="bar">c3</div>
                </div>
            </div>
        </div>
    </body>
</html>

我已将ExtendedSelenium2Library作为我的Robot脚本中的库包含在内,到目前为止,我的测试用例如下所示:

Click on the first bar of the Book Sales bar chart
    Click Element    xpath=//child::div[@class="bar_chart" and ./h1/text()="Book Sales"]//div[@class="bar" and 1]

毋庸置疑,我的测试用例因以下错误而失败:

ValueError: Element locator 'xpath=//child::div[@class="bar_chart" and ./h1/text()="Book Sales"]//div[@class="bar" and 1]' did not match any elements.

这是我的Xpath的细分和我试图遵循的逻辑:

//子:: DIV [@class =&#34; bar_chart&#34;和./h1/text()="Book Sales&#34;] 应该选择div类别为 bar_chart 并且有一个孩子的div子节点h1 节点包含字符串图书销售

在该选择中, // div [@class =&#34; bar&#34;和1]&#39; 的目的是选择第一个 div节点,其类 bar

我真的很感激任何可以帮助我实现自动点击图书销售图表第一栏的目标的提示或指示,而不依赖于id属性(每次刷新页面时它们都会变化很好)并且可以正常工作即使条形图在页面周围移动(图表本身的结构也不太可能改变,但图表的顺序可能会改变,或者整个chart_and_graphs div可能会移动到页面的顶部/底部...在此先感谢!

1 个答案:

答案 0 :(得分:0)

让我试着解释一下你的表达没有用的东西,然后给出一个应该用于预期目的的样本。

表达式的第一个路径 - // child :: div [@class =&#34; bar_chart&#34;和./h1/text()="Book Sales&#34;] - 没有抓住你的想法。
它选择所有元素,它们具有div的直接后代(子),具有该类值,并且具有h1子项本身。换句话说,它选择<div class="bar_chart">

现在,从它开始,//div[@class="bar" and 1]将选择具有类值的div,而这就是它。 1不会是您希望它的元素位置 - and将建立逻辑连接,而1将始终评估为真 - 即它{&#39}不需要的。

我无法说明未找到元素的原因,您提供的示例xpath会返回class="bar"所有div节点(您可以自己尝试here

假设位置条件固定为工作 - 那么表达式仍然不会返回您期望的结果,如第二部分所示,它将返回第一个div,其中class =&#34; bar&#34;。如果&#34; Pen Sales&#34;是在#34;图书销售&#34;?之前好吧,你可以在那里得到第一个项目,不过你是在书本之后。

所以,让我们开始吧 - 获得图书销售的div:

//h1[text()="Bag Sales"]/following-sibling::div[@class="bar_area"][1]

此表达式将获得带有目标文本的h1,然后将选择它的第一个后续div兄弟。现在我们已经定位在正确的div包围酒吧,让第一个孩子上课#34; bar&#34;很容易:

/div[@class="bar"][1]

所以完整的表达是:

//h1[text()="Bag Sales"]/following-sibling::div[@class="bar_area"][1]/div[@class="bar"][1]

顺便说一下,获取此源的正确xpath的一个主要问题是结构 - 所有目标元素都是平面布局,而不是按层次分组(例如h1div类=&#34; bar_area&#34;在公共div中组合在一起)。我想你无法控制它,但如果它是一个层次结构,那么使用它将是微不足道的。