How to select a combo list text item defined within in a div tag where all div tags have the same class name using watir webdriver - watir-webdriver

I am trying to select an item in a combo-list with text "1 : 272988" where the combo list is defined as a list of div tags all with the same class name as below:
<div style="width: 108px; height: 300px;" id="ext-gen334" class="x- combo-list-inner">
<div class="x-combo-list-item">1 : 1066</div>
<div class="x-combo-list-item">1 : 2132</div>
<div class="x-combo-list-item">1 : 4265</div>
<div class="x-combo-list-item x-combo-selected">1 : 8530</div>
<div class="x-combo-list-item">1 : 17061</div>
<div class="x-combo-list-item">1 : 34123</div>
<div class="x-combo-list-item">1 : 68247</div>
<div class="x-combo-list-item">1 : 136494</div>
<div class="x-combo-list-item">1 : 272988</div>
<div class="x-combo-list-item">1 : 545977</div>
I have tried the following options below but all result in a watir unknown object exception error
#browser.div(:class => "x-combo-list-inner", :text => "1 :272988").click
#browser.div(:class => "x-combo-list-inner").div(:class => "x-combo-list-item", :text => "1 : 272988").click
#browser.div(:class => "x-combo-list-inner").div(:class => "x-combo-list-item", :index => 8)
#browser.div(:class => "x-combo-list-inner").div(:text => "1 : 272988").click
For all the above I have also tried substituting
.click
with
.wait_until_present
and get watir timeout exception errors. I have also tried performing a
.exists?
for all the above options and they return false.
The results would suggest that the combo list items don't actually exist however when I check the containing div elements that hold the combo list items as below
puts #browser.div(:class => "x-combo-list-inner").div(:class => "x-combo-list-item").exists?
a true value returned.
Would greatly appreciate any other ideas as I have run out.

The problem with nested element locators, ie #browser.div(:class => "x-combo-list-inner").div(:class => "x-combo-list-item", :text => "1 : 272988") is that Watir only looks in the first matching parent element.
That means that in an HTML like:
<body>
<div class="x-combo-list-inner">
<div class="x-combo-list-item">Wrong Text</div>
</div>
<div class="x-combo-list-inner">
<div class="x-combo-list-item">1 : 272988</div>
</div>
</body>
Watir would be looking in the first div element, which only has the list item "Wrong Text". You have a couple of options.
If the list item is unique on the page, the easiest solution is to remove the parent element locator:
#browser.div(:class => "x-combo-list-item", :text => "1 : 272988")
If it is not unique, you have to tell Watir which combo list to use. As mentioned in the comments, you could tell Watir to use a specific index:
#browser.div(:class => "x-combo-list-inner", :index => 1).div(:class => "x-combo-list-item", :text => "1 : 272988")
or
#browser.divs(:class => "x-combo-list-inner")[1].div(:class => "x-combo-list-item", :text => "1 : 272988")
However, care should be taken when using index since adding another combo list could unexpectedly break the test. If possible, you should see if there is something within the combo lists that can be used to differentiate them. For example, an id or user visible text.

Related

How to set indentation of code containing multiple child items(div's)

I have a piece of code containing multiple child div. Now, I'm trying to change its indentation from 4 to 2, what can be the right way?
Note: I've tried selecting the code and pressing "ctrl + [" and also "shift + tab", but the issue is that it moves the complete div to right, that's cool but the child elements are still placed at 4 space indentation relative to parent. How can I set the spaces of each element from its parent div to be "2"?
<div className="showItems">
{
items.map((elem) => {
return (
<div className="eachItem" key={elem.id}>
<h3>{elem.name}</h3>
<div className="todo-btn">
<button title="Edit Item" onClick={() => completeItem(elem.id)}>Done</button>
<button title="Edit Item" onClick={() => editItem(elem.id)}>Edit</button>
<button title="Delete Item" onClick={() => deleteItem(elem.id)}>Delete</button>
</div>
</div>
)
})
}
</div>

Laravel dynamic select box return index instead of value from collection

I am trying to make a select box that return value from $collection, but it gives me index of the selection instead of value.
screenshot:output of my code
screenshot:browser source code view
<div class="form-group">
{!! Form::label('Supervisor') !!}<br />
{!! Form::select('supervisor_id', $lecturers, null,
array('placeholder' => '----------------','class' => 'form-control')) !!}
</div>
and when it's show in browser source code view:
<option value="">----------------</option>
<option value="0">1111111111</option>
<option value="1">1212121212</option>
Anyone who know the syntax of laravel form to make this dynamic form gives value of $lecturers please help.
Ok here we go.
First in your controller, when you are getting the lecturers list, make sure you pluck just the name and the id...in this order:
$lecturers = Lecturer::pluck('name', 'id');
Then in your view:
{{Form::select('lecturer_id', $lecturers, null, ['class' => 'form-control'])}}
Thats all.
The array of lecturers, that you plucked will be divided into "id" and "values", hence the order of plucking is important.
Now, in your form source, you will see that the option value will be lecturers ids like "1, 2, 3" etc while the "selectable" options shown to users will be the names of the lecturers.
Like this:
<select class="form-control" name="lecturers_id"><option value="1">John Doe</option><option value="2">Jane Doe</option></select>
Try these and lets know your result.

Laravel Form: Input Button Not Showing HTML Icon

I'm creating a button with Form at Laravel:
{!! Form::submit('<i class="fa fa-trash"></i>', ["class"=>"btn btn-default"]) !!}
The button text becomes:
<i class="fa fa-trash"></i>
I see only this string, not the icon: how to fix it?
Try to use Form::button instead of Form::submit:
{{ Form::button('<i class="fa fa-trash"></i>', ['type' => 'submit', 'class' => 'btn btn-default'] ) }}
It will create a button tag with type submit instead of an input tag.
This way the html of the icon should be rendered inside the tag content and should be visible.
Instead, by using an input tag like you are doing, the html string of the icon would be printend inside the value attribute of the input tag, and here it couldn't be rendered as valid html

Unable to locate element error

I am getting an error when trying to click a "Sponsors" link on the page:
unable to locate element, using {:href=>"/Sponsors", :target=>"", :tag_name=>"a"}
Here is the line I am using:
browser.div(:class => "pageContainer").header(:class => "page-header")
.div(:class => "container").nav.ul(:class => "nav nav-pills")
.li(:class => "", :index => 2).a(:href => "/Sponsors", :target => "").click
(FYI: I've tried using index 0 through 4, and removing the index; all resulted in the same error)
Below is the code:
<div class="pageContainer">
<header class="page-header">
<div class="container">
<nav>
<ul class="nav nav-pills">
<li class>...</li>
<li class>...</li>
<li class="dropdown open">...</li>
<li class>
<a href="/Sponsors" target"">
Sponsors
</a>
</li>
<li class="dropdown">...</li>
</ul>
</nav>
Posting as an answer since OP indicates that it's a solution.
Instead of qualifying the whole path to the element, use a single locator (which should still locate the element and should be less fragile if ancestor elements are changed):
browser.a(:href => "/Sponsors").click
browser.a(:text => "Sponsors").click

Dynamically added elements - using $(this)

When adding a element to the dom dynamically like this:
row = """
<div class="ipad-row">
<h3>Sample Row</h3>
<div id="wrapper-placeholder">
<div class="scrollView" style="">
<a class="btn btn-primary add-row-item">Add an item</a>
</div>
</div>
</div>
"""
$(".add-row").live "click", ->
$(".ipad .body").append row
false
How come when I try and get this from the a link inside that row element, I get window:
$(".add-row-item").live "click", =>
f = $ this
console.log f // this logs window object, not the link element?
f.parent().append row_item
Can someone please explain this behavior and how i can use $(this) like you would if the element did exist when the dom loaded?
Thanks
=> changes this to the this in the parent context:
$(".add-row-item").live "click", =>
f = $(this)
compiles to
var _this = this;
$(".add-row-item").live("click", function() {
var f = $(_this);
Use -> instead, which won't modify this.