button in a nested table that has dynamic id - watir-webdriver

I am trying to click on a button in a table cell that has a dynamic name with a prefix of button_keep
this is the unique path that firebug has pointed out for the table cell.
#mergePatientsSelectedTable > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(2) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(1) > td:nth-child(1)
I'm trying to get there using the following but it does not find the button.
b.table(:id => "mergePatientsSelectedTable").tbody{2}.tr{1}.td{2}.table{1}.tbody{1}.tr{1}.td{1}.button(:index => 0).button(:name => /button_keep/).click
I have tried to flash on the cells and use IRB yet it continues to give me an assert that cannot find the button.
Any suggestions . thank you

You do not need to write out the whole path. Each method/locator looks in all descendents, not just direct children. Using entire paths can make the code quite brittle.
So why not just locate the button based on the known attributes:
b.table(:id => "mergePatientsSelectedTable").button(:name => /button_keep/).click
But to explain why you were having problems with your solution, doing tbody{2} actually returns the first tbody element (not the second). The {2} is a block that gets ignored.
For example, consider the html:
<div>hi</div>
<div>bye</div>
You can see the first div gets returned when using a block:
b.div{2}.text
#=> "hi"
To get the second div, you can either use the index locator or get the second element of the collection:
b.div(:index => 1).text
#=> "bye"
b.divs[1].text
#=> "bye"
So if you really wanted to do the entire path, you could have done:
b.table(:id => "mergePatientsSelectedTable").tbody(:index => 1).tr.td(:index => 1).table.tbody.tr.td.button(:name => /button_keep/).click
Note that:
nth-child is 1-based index while Watir uses a 0-based index.
If you want the first match, you do not need to include the index - :index => 0 is assumed.

Related

Need help - How to loop through a list and/or a map

Scala is pretty new for me and I have problems as soon as a leave the gatling dsl.
In my case I call an API (Mailhog) which responds with a lot of mails in json-format. I can’t grab all the values.
I need it with “jsonPath” and I need to “regex” as well.
That leads into a map and a list which I need to iterate through and save each value.
.check(jsonPath("$[*]").ofType[Map[String,Any]].findAll.saveAs("id_map"))
.check(regex("href=3D\\\\\"(.*?)\\\\\"").findAll.saveAs("url_list"))
At first I wanted to loop the “checks” but I did’nt find any to repeat them without repeating the “get”-request too. So it’s a map and a list.
1) I need every value of the map and was able to solve the problem with the following foreach loop.
.foreach("${id_map}", "idx") {
exec(session => {
val idMap = session("idx").as[Map[String,Any]]
val ID = idMap("ID")
session.set("ID", ID)
})
.exec(http("Test")
.get("/{ID}"))
})}
2) I need every 3rd value of the list and make a get-request on them. Before I can do this, I need to replace a part of the string. I tried to replace parts of the string while checking for them. But it won’t work with findAll.
.check(regex("href=3D\\\\\"(.*?)\\\\\"").findAll.transform(raw => raw.replace("""=\r\n""","")).saveAs("url"))
How can I replace a part of every string in my list?
also how can I make a get-request on every 3rd element in the list.
I can't get it to work with the same foreach structure above.
I was abole to solve the problem by myself. At first I made a little change to my check(regex ...) part.
.check(regex("href=3D\\\\\"(.*?)\\\\\"").findAll.transform(_.map(raw => raw.replace("""=\r\n""",""))).saveAs("url_list"))
Then I wanted to make a Get-Request only on every third element of my list (because the URLs I extracted appeared three times per Mail).
.exec(session => {
val url_list =
session("url_list").as[List[Any]].grouped(3).map(_.head).toList
session.set("url_list", url_list)
})
At the end I iterate through my final list with a foreach-loop.
foreach("${url_list}", "urls") {
exec(http("Activate User")
.get("${urls}")
)
}

Mojolicious, Mojo::DOM select tag by contains text

Is there analog ":contains()"(JQuery, JSoup) selector in Mojolicious?
Selector ":contains('text') ~ td + td" work in JQuery and JSoup. How can I convert it to Mojolicious selector?
http://api.jquery.com/contains-selector/
Description: Select all elements that contain the specified text.
version added: 1.1.4jQuery( ":contains(text)" ) text: A string of text
to look for. It's case sensitive.
http://jsoup.org/apidocs/org/jsoup/select/Selector.html
:contains(text) elements that contains the specified text. The search
is case insensitive. The text may appear in the found element, or any
of its descendants.
Mojolicious analog?
Untested, but I would go in the direction of
$dom->find('*')
->grep(sub { $_->all_text =~ /text/ })
->map('following', 'td')
->map('find', 'td')
(if you have something more specific before your :contains, like at least a tag name selector, then replace the * with that, which should greatly help the performance).
Few experiment with hobbs code and I can repeat JQuery, JSoup selector result:
:contains('some string') ~ td + td
Mojo:
$dom
-> find('*')
-> grep(sub { $_ -> text =~ /some string/; })
-> map('following', '~ td + td')
-> flatten;
But, I don't think it's universal and best way to do such select. Just for start.
text
Extract text content from this element only (not including child
elements), smart whitespace trimming is enabled by default.
flatten
Flatten nested collections/arrays recursively and create a new
collection with all elements.

Yii2-mongodb: how to add database fetched items in dropdown list

I am trying to add the team names(to be fetched from mongoDB) in the form to let user select the form name.
I am not getting how to add the database fetched form names in the dropdown list.
It should search based on organization_id first & then form_name.
what i am doing is this:
<?= $form->field($model1, 'form_name')->dropDownList(ArrayHelper::map(CreateTeam::find(array('organization_id' => Yii::$app->session['organization_id']))->all(), 'form_name')); ?>
It is showing me an error that missing the third argument. What could be the third argument in that case???
I went through issue with fetching record from country collection to serve record in state form
I got solution as below (considering as my state form)
use app\models\Countries;
use yii\helpers\ArrayHelper;
$countries=Countries::find()->all();
$listData=ArrayHelper::map(Countries::find()->all(),function ($model){return (string)$model->_id;},'name');
echo $form->field($model, 'countries_id')->dropDownList($listData, ['prompt'=>'Select...']);
Hope I was able to let you understand !
$collection2 = Yii::$app->mongodb->getCollection('teamdashboard');
$models = $collection2->find(array('organization_id' => Yii::$app- >session['organization_id']));
$items = ArrayHelper::getColumn($models, 'team_name');
return $this->render('teamdashboard', ['model1' => $model1, 'model2' => $model2, 'items' => $items]);
This one works fine for mongodb...
Yes, in ArrayHelper::map() first three parameters are required, so you are definitely calling this method wrong.
Check out official documentation for map().
The second parameter represents the actual values in database (usually they are primary keys), the third - readable text.
Assuming your primary key is id it should be:
$models = CreateTeam::find([
'organization_id' => Yii::$app->session['organization_id'],
])->all();
$items = ArrayHelper::map($models, 'id', 'form_name');
<?= $form->field($model1, 'form_name')->dropDownList($items) ?>

Lift - how to get default value of select using WiringUI

I have an issue with getting default value of select dropdown.
i have fruits val:
val fruits = List("apple", "banana", "other")
and i render a tr with:
<tr id={ theLine.guid }>
<td>
{
SHtml.ajaxSelect(fruits, Full(fruits(0)),
s => {
mutateLine(theLine.guid) {
l => Line(l.guid, l.name, s, l.note)
}
Noop
})
}
</td>
(...)
on page html is rendered correctly with option selected="selected", but when i try to save it to DB i get empty value of fruit. if i change option to 'other' and then i select it back to 'apple', it saves right value.
i add also a println function to addLine to see what values are in this vector, and there is empty value if i dont change fruit option, so i suppose that it is not problem when i process lines to save it to DB.
can you help me with this?
thanks
Gerard
Before you change your select option, you are not triggering the event that calls your function. The function is bound to onChange and that only gets fired when the value changes.
To fix, you could either: Start with an option like "Select a value". This would require the user to change the item, but is the only way to trigger the onchange.
If you don't want to do that, you could add a button and add your logic to a button click handler that would get called when submitted. Something like this should help - you'll need to bind it to your output, either inline as you provided, or via CSS Selectors:
var selected = Full(fruits(0))
SHtml.ajaxSelect(fruits, selected,
s => {
selected = Full(s)
Noop
})
SHtml.ajaxSubmit("Submit", () => {
mutateLine(theLine.guid) {
l => Line(l.guid, l.name, selected, l.note)
}
})

Getting an "Odd number of elements in hash assignment" error

I'm getting the following error when running a Perl script
Odd number of elements in hash assignment at GenerateInterchangeFromIntegrationManifest.pl line 197.
{
"Change list" : "0"
}
This is the script:
my %labelFieldMap = (IUItemName => convertIuItemName,
Changelist => sub {},
IUItemLevel => createNormalConvert('iuItemLevel'),
ContactPOC => \&convertContacts,
Cspec => \&convertCspec,
IsNew => createBooleanConvert('isNew'),
Submitter => createNormalConvert('submitter'),
LabelType => createNormalConvert('type'),
Revision => createNestedConvert('component', 'revision'),
RevisionName => sub {},
ComponentBaseName => createNestedConvert('component', 'baseName'),
Version => createNestedConvert('component', 'version'),
PLMapping => createNormalConvert('plMapping'),
BidMapping => createNormalConvert('bidMapping'),
ClientId => createNormalConvert('clientId'),
Path => \&convertPath,
ExtendedData => \&convertExtendedData);
Can any one help me resolve this issue?
There are several subroutine calls in assignment to the hash that could be returning lists with an even number of elements (which would make the list count odd overall, and also change which data is keys and which values from that point in the list on, which is probably worse for you). As Dallaylaen has pointed out in comments, this could simply be a line which returns "nothing", return; which will evaluate to empty list (), i.e. an even length of 0, in list context. All the subroutine calls in the question code will be evaluated in list context.
I would suggest a simple debug technique:
Comment out all the lines with a function call, that should remove the warning.
Then add back a few at a time and re-test.
When the warning re-appears, you will have isolated the problem to one of a few subroutines.
Repeat until you know which one.
Then investigate that call to see how you might fix it.