SGM
SGM

Reputation: 113

Ruby watir webdriver - how to click on a div link that is dynamically created

I have a link in my web app that looks like this when inspected in developer tools -

<div class="runnable-item alt" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}"><!-- ngIf: item.working -->Rep</div>

I need to be able to click on it from within Ruby code using watir webdriver. I could click on buttons and edit fields so far successfully with code similar to:

browser.text_field(id: 'user').set 'test1'
browser.button(id: 'submitBtn').click
browser.a(id: 'start-process').click

Now how do I auto-click on a div element as shown above?

Here is a more full HTML code -

<div class="row">
<!-- ngRepeat: list in lists --><div ng-repeat="list in lists" class="">
<div class="col-sm-6"><h4>Services</h4>
<!-- ngIf: list.items === undefined -->
<!-- ngIf: list.message --><!-- ngRepeat: item in list.items | orderBy:'name' track by item.id -->
<div ng-repeat="item in list.items | orderBy:'name' track by item.id" class=""><div class="runnable-item" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}">
<!-- ngIf: item.working -->Excel Examples Main (Start here)</div></div>
<!-- end ngRepeat: item in list.items | orderBy:'name' track by item.id -->
<div ng-repeat="item in list.items | orderBy:'name' track by item.id" class=""><div class="runnable-item alt" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}">
<!-- ngIf: item.working -->Excel Examples</div></div>
<!-- end ngRepeat: item in list.items | orderBy:'name' track by item.id -->
<div ng-repeat="item in list.items | orderBy:'name' track by item.id" class=""><div class="runnable-item" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}"><!-- ngIf: item.working -->Hello World</div></div>
<!-- end ngRepeat: item in list.items | orderBy:'name' track by item.id --></div></div>
<!-- end ngRepeat: list in lists --><div ng-repeat="list in lists" class="">
<div class="col-sm-6"><h4>Processes</h4><!-- ngIf: list.items === undefined --><!-- ngIf: list.message -->
<!-- ngRepeat: item in list.items | orderBy:'name' track by item.id -->
<div ng-repeat="item in list.items | orderBy:'name' track by item.id" class=""><div class="runnable-item" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}">
<!-- ngIf: item.working -->CompletedExample</div></div>
<!-- end ngRepeat: item in list.items | orderBy:'name' track by item.id -->
<div ng-repeat="item in list.items | orderBy:'name' track by item.id" class=""><div class="runnable-item alt" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}">
<!-- ngIf: item.working -->SimpleActiveExample</div></div>
<!-- end ngRepeat: item in list.items | orderBy:'name' track by item.id -->
<div ng-repeat="item in list.items | orderBy:'name' track by item.id" class=""><div class="runnable-item" ng-click="list.click(item)" ng-class="{'alt': $odd, 'disabled': item.working}">
<!-- ngIf: item.working -->Standard HR</div></div>
<!-- end ngRepeat: item in list.items | orderBy:'name' track by item.id --></div></div><!-- end ngRepeat: list in lists --></div>
...
...

Upvotes: 0

Views: 2363

Answers (2)

matic
matic

Reputation: 311

If multiple items have the same class there are a few options.

  1. You can grab all of them using @browser.divs(class: "runnable-item alt ") then iterate over the result using .each do |element| checking it for some x property.
  2. Make your selection more specific @browser.div(css: "parent runnable-item:nth-child(2)", text: /text from div/)

Overall your question needs more context. Give us some more of the html tree so we understand how to solve the problem. Do you want a specific button, a random button, etc.

Update: You still need to be more specific. Do you want "Processs" OR "Services" or just any random div with the class "runnable-item alt" clicked. If it really is any random button the following should be good enough: @browser.divs(class: "runnable-item alt").sample.click

If you want to randomly select an item from either the Process section or Services section I would do something like the following:

case Random.new.rand(2) 
when 0
  div_section = @browser.h4(text: /Processes/).parent
  div_section.div(class: "runnable-item alt").click
when 1
  div_section = @browser.h4(text: /Services/).parent
  div_section.div(class: "runnable-item alt").click
end

In either case you need to be more deterministic about what you want to do with the test. Create variance with multiple test cases that have a defined workflow rather then one test case that randomly clicks different buttons.

Upvotes: 2

SGM
SGM

Reputation: 113

It turns out the solution was simpler than I anticipated. Using Watir you can select div elements based on text value, so, it works great for my use case.

The code to click/call "CompletedExample" from above HTML would look like -

b.div(:text, 'CompletedExample').click

Upvotes: 0

Related Questions