使用Watir自动扩展树并选择复选框

时间:2013-03-12 21:16:36

标签: ruby checkbox tree watir treenode

在网站上,有一个节点树,每个节点都与一个复选框相关联。然后,这些节点进一步扩展为更多复选框。 它看起来类似于[]表示复选框的以下内容:

+ [] All
   + [] Fruit
   + [] Vegetables

然后扩展看起来像这样:

+ [] All
   - [] Fruit
        [] apple
   - [] Vegetables
        [] potato
        [] cucumber

屏幕底部有一个按钮,按下后会显示所选项目的价格。

我想在Watir中编写一个执行以下事件序列的脚本:

1) Expands the node Fruit
2) Checks apple
3) Clicks the run button
4) Unchecks apple
5) Expands the node Vegetables
6) Checks potato
7) Clicks the run button
8) Unchecks potato
etc.. for all checkboxes and nodes

apple复选框的标签如下所示:

<td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;" class="">
  <input type="checkbox" name="ContentPlaceHolder1_tvPartnersn2CheckBox" id="ContentPlaceHolder1_tvPartnersn2CheckBox">
  <a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$tvPartners','s0\\0\\189')" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,'ContentPlaceHolder1_tvPartnerst2');" id="ContentPlaceHolder1_tvPartnerst2">
  <font style="color:#FF0000;">apple</font>
</td>

此外,稍后会有更多节点和项目添加到列表中,因此我需要脚本将其考虑在内并按顺序浏览复选框,而不调用复选框的特定ID。

任何帮助解决这个问题的人都会非常感激。非常感谢你!

更新: 我提出了这个代码,但我想检查最后一个复选框/节点,而不是硬编码for循环。我还想跳过水果和蔬菜等节点的复选框。

for n in (1...250)
  nodename = "ContentPlaceHolder1_tvPartnersn" + n.to_s
  if ie.a(:id => nodename).exists?
    ie.link(:id, nodename).click
  end
end

ie.checkbox(:id => "ContentPlaceHolder1_tvPartnersn0CheckBox").clear

x = 1
for r in (1...250)
  checkboxname = "ContentPlaceHolder1_tvPartnersn" + x.to_s + "CheckBox"
  nodename = "ContentPlaceHolder1_tvPartnersn" + r.to_s

  if ie.a(:id => nodename).exists?
    x = x+1
    checkboxname = "ContentPlaceHolder1_tvPartnersn" + x.to_s + "CheckBox"
  end

  if ie.checkbox(:id => checkboxname).exists?
    ie.checkbox(:id => checkboxname).set
    puts x
    ie.checkbox(:id => checkboxname).clear    
  end

  x = x + 1
end

更新:这里有更多的HTML。我实际上有一个哈希设置为itemlist [[n,“item”]] = item,例如itemlist [[1,“item”]] = apple,其中包含我需要检查价格的所有项目。有没有办法/更容易看到每个复选框的文本是什么,然后如果itemlist.has_value?(checkbox_text)然后选中该框并将该文本分配给另一个哈希?基本上,有没有办法根据文本而不是复选框的ID来检查框?

<td><a id="ContentPlaceHolder1_tvPartnersn0" href="javascript:TreeView_ToggleNode(ContentPlaceHolder1_tvPartners_Data,0,document.getElementById(&#39;ContentPlaceHolder1_tvPartnersn0&#39;),&#39;-&#39;,document.getElementById(&#39;ContentPlaceHolder1_tvPartnersn0Nodes&#39;))"><img src="/WebResource.axd?d=VNrMPzAA2o87avzl3UgiY8OisS6wrOp46COe6QqNhDQHCsy9zX-GTuzHAKk7njulOEns3hNoLIxbv9x1bv530iY_Shsd9ZHlF3pm4jNQi6u0zB6atkT0-K9kirzHDQNHYxlY8Q2&amp;t=634963835619397560" alt="Collapse All (133,060)" style="border-width:0;" /></a></td><td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;"><input type="checkbox" name="ContentPlaceHolder1_tvPartnersn0CheckBox" id="ContentPlaceHolder1_tvPartnersn0CheckBox" /><a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack(&#39;ctl00$ContentPlaceHolder1$tvPartners&#39;,&#39;s0&#39;)" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,&#39;ContentPlaceHolder1_tvPartnerst0&#39;);" id="ContentPlaceHolder1_tvPartnerst0">All (133,060)</a></td>
                </tr>
            </table><div id="ContentPlaceHolder1_tvPartnersn0Nodes" style="display:block;">
                <table cellpadding="0" cellspacing="0" style="border-width:0;">
                    <tr>
                        <td><div style="width:20px;height:1px"></div></td><td><a id="ContentPlaceHolder1_tvPartnersn1" href="javascript:TreeView_ToggleNode(ContentPlaceHolder1_tvPartners_Data,1,document.getElementById(&#39;ContentPlaceHolder1_tvPartnersn1&#39;),&#39;t&#39;,document.getElementById(&#39;ContentPlaceHolder1_tvPartnersn1Nodes&#39;))"><img src="/WebResource.axd?d=D2aGfOHUjBmg4quHNr-mKkyc5juoGHdurzZqtoCU3qo2d457eKX9x0d2AS3LrrQULzPjC-9wC6hLlMxSFEvU6c9r8LmzgOeKWAi6ouEEkShvclKr0&amp;t=634963835619397560" alt="Expand Ace Communications Group (0) &lt;img src=&#39;images/emergency.png&#39; alt=&#39;alert&#39; />" style="border-width:0;" /></a></td><td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;"><input type="checkbox" name="ContentPlaceHolder1_tvPartnersn1CheckBox" id="ContentPlaceHolder1_tvPartnersn1CheckBox" /><a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack(&#39;ctl00$ContentPlaceHolder1$tvPartners&#39;,&#39;s0\\0&#39;)" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,&#39;ContentPlaceHolder1_tvPartnerst1&#39;);" id="ContentPlaceHolder1_tvPartnerst1">Fruit </a></td>
                    </tr>
                </table><div id="ContentPlaceHolder1_tvPartnersn1Nodes" style="display:none;">
                    <table cellpadding="0" cellspacing="0" style="border-width:0;">
                        <tr>
                            <td><div style="width:20px;height:1px"></div></td><td><div style="width:20px;height:1px"><img src="/WebResource.axd?d=UZyrk961AUQRa1Dg14aXeNUU3AZcfF9PiakU0o_cO8MfbyWz58k50vr47p2ICDOjgAqF5UX_lVIhbj_y2BqKRU5Xwhic3cBNooK1CBd_cGP6COn60&amp;t=634963835619397560" alt="" /></div></td><td><img src="/WebResource.axd?d=OftTkmJCEf6tGohvvdo_cbMxdnyHMLxScANk1YxbAhfKKp3_gvqoKFAIbK4gGFAKMagH78cKVSIS61WrK5fGcCaHWVUMPjXLTtDZIJISdqqtXFNI0&amp;t=634963835619397560" alt="" /></td><td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;"><input type="checkbox" name="ContentPlaceHolder1_tvPartnersn2CheckBox" id="ContentPlaceHolder1_tvPartnersn2CheckBox" /><a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack(&#39;ctl00$ContentPlaceHolder1$tvPartners&#39;,&#39;s0\\0\\189&#39;)" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,&#39;ContentPlaceHolder1_tvPartnerst2&#39;);" id="ContentPlaceHolder1_tvPartnerst2"><font style='color:#FF0000;'>apple</font>  </a></td>
                        </tr>
                    </table>
                </div><table cellpadding="0" cellspacing="0" style="border-width:0;">
                    <tr>
                        <td><div style="width:20px;height:1px"></div></td><td><a id="ContentPlaceHolder1_tvPartnersn3" href="javascript:TreeView_ToggleNode(ContentPlaceHolder1_tvPartners_Data,3,document.getElementById(&#39;ContentPlaceHolder1_tvPartnersn3&#39;),&#39;t&#39;,document.getElementById(&#39;ContentPlaceHolder1_tvPartnersn3Nodes&#39;))"><img src="/WebResource.axd?d=D2aGfOHUjBmg4quHNr-mKkyc5juoGHdurzZqtoCU3qo2d457eKX9x0d2AS3LrrQULzPjC-9wC6hLlMxSFEvU6c9r8LmzgOeKWAi6ouEEkShvclKr0&amp;t=634963835619397560" alt="Expand Advantage (0)" style="border-width:0;" /></a></td><td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;"><input type="checkbox" name="ContentPlaceHolder1_tvPartnersn3CheckBox" id="ContentPlaceHolder1_tvPartnersn3CheckBox" /><a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack(&#39;ctl00$ContentPlaceHolder1$tvPartners&#39;,&#39;s0\\0&#39;)" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,&#39;ContentPlaceHolder1_tvPartnerst3&#39;);" id="ContentPlaceHolder1_tvPartnerst3">Vegetable</a></td>
                    </tr>
                </table><div id="ContentPlaceHolder1_tvPartnersn3Nodes" style="display:none;">
                    <table cellpadding="0" cellspacing="0" style="border-width:0;">
                        <tr>
                            <td><div style="width:20px;height:1px"></div></td><td><div style="width:20px;height:1px"><img src="/WebResource.axd?d=UZyrk961AUQRa1Dg14aXeNUU3AZcfF9PiakU0o_cO8MfbyWz58k50vr47p2ICDOjgAqF5UX_lVIhbj_y2BqKRU5Xwhic3cBNooK1CBd_cGP6COn60&amp;t=634963835619397560" alt="" /></div></td><td><img src="/WebResource.axd?d=yCq0KCcfK0lqwrgCU1UxuFJ0bJHMKjxD6S5t8OvIWXwTUBOYh1ZiQA4lD3ZpRuMNI-itrPIn3_rFzvZtrMP5g7PyyensT-Z003WldrY9pIgMSY5p0&amp;t=634963835619397560" alt="" /></td><td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;"><input type="checkbox" name="ContentPlaceHolder1_tvPartnersn4CheckBox" id="ContentPlaceHolder1_tvPartnersn4CheckBox" /><a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack(&#39;ctl00$ContentPlaceHolder1$tvPartners&#39;,&#39;s0\\0\\119&#39;)" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,&#39;ContentPlaceHolder1_tvPartnerst4&#39;);" id="ContentPlaceHolder1_tvPartnerst4">potato</a></td>
                        </tr>
                    </table><table cellpadding="0" cellspacing="0" style="border-width:0;">
                        <tr>
                            <td><div style="width:20px;height:1px"></div></td><td><div style="width:20px;height:1px"><img src="/WebResource.axd?d=UZyrk961AUQRa1Dg14aXeNUU3AZcfF9PiakU0o_cO8MfbyWz58k50vr47p2ICDOjgAqF5UX_lVIhbj_y2BqKRU5Xwhic3cBNooK1CBd_cGP6COn60&amp;t=634963835619397560" alt="" /></div></td><td><img src="/WebResource.axd?d=yCq0KCcfK0lqwrgCU1UxuFJ0bJHMKjxD6S5t8OvIWXwTUBOYh1ZiQA4lD3ZpRuMNI-itrPIn3_rFzvZtrMP5g7PyyensT-Z003WldrY9pIgMSY5p0&amp;t=634963835619397560" alt="" /></td><td onmouseover="TreeView_HoverNode(ContentPlaceHolder1_tvPartners_Data, this)" onmouseout="TreeView_UnhoverNode(this)" style="white-space:nowrap;"><input type="checkbox" name="ContentPlaceHolder1_tvPartnersn5CheckBox" id="ContentPlaceHolder1_tvPartnersn5CheckBox" /><a class="ContentPlaceHolder1_tvPartners_0" href="javascript:__doPostBack(&#39;ctl00$ContentPlaceHolder1$tvPartners&#39;,&#39;s0\\0\\1&#39;)" onclick="TreeView_SelectNode(ContentPlaceHolder1_tvPartners_Data, this,&#39;ContentPlaceHolder1_tvPartnerst5&#39;);" id="ContentPlaceHolder1_tvPartnerst5">cucumber</a></td>
                        </tr>

1 个答案:

答案 0 :(得分:0)

您应该使用集合来查找符合特定条件的所有元素,而不是将循环硬编码为1到250。

所以而不是

for n in (1...250)
  nodename = "ContentPlaceHolder1_tvPartnersn" + n.to_s
  if ie.a(:id => nodename).exists?
    ie.link(:id, nodename).click
  end
end

应该是

ie.links(:id => /ContentPlaceHolder1_tvPartnersn/).each do |link|
  link.click
end

也可以写成

ie.links(:id => /ContentPlaceHolder1_tvPartnersn/).each(&:click)

这里的关键是ie.links(:id => /ContentPlaceHolder1_tvPartnersn/)返回符合条件或定位符的所有链接。正则表达式(regex)用于检查id,因为这允许id的部分匹配(即包含文本ContentPlaceHolder1_tvPartnersn的任何链接ID)。

同样的逻辑可以应用于你的脚本的其余部分(请注意,如果没有完整的html示例,我猜测你的代码会做什么):

#Expand the entire tree
ie.links(:id => /ContentPlaceHolder1_tvPartnersn/).each(&:click)

#Clear the first checkbox
ie.checkbox(:id => "ContentPlaceHolder1_tvPartnersn0CheckBox").clear

#Set and clear each checkbox
checkbox_id = /ContentPlaceHolder1_tvPartnersn/
ie.checkboxes(:id => checkbox_id).each do |checkbox|
  checkbox.set
  puts checkbox.id
  checkbox.clear
end

根据'fruit'和'vegetable'节点的html,这些代码可能已经忽略了它们。否则,您可能需要更改checkbox_id或添加条件检查。

<强>更新

如果要根据文本设置复选框,可以执行以下操作:

ie.td(:text => 'apple').checkbox.set