Angular 5: Combination of *ngFor and ngIf with a whole array - angular5

I have an array which i iterate with ngFor in the view as shown below.
I want to hide the button if all elements of y.errortyp are nottested.
How can i achieve this functionality? I tried some combinations of ngIf, but can not find a solution.
<...>
<tr *ngFor="let x of x">
<td> x.name</td>
<td *ngFor="let y of x.results">
<div *ngIf="y.errortyp == 'Error1'" class="red"></div>
<div *ngIf="y.errortyp == 'nottested'" class="grey"></div>
</td>
<td>
<button type="button" class="btn btn-default btn-lg btn-block" aria-label="Left Align"
(click)="download(x)">
Download
</button>
</td>
<...>

Related

Dynamically added HTML element after click event

I don't know how to add dynamic content in my Vue js 2 app. I'd like to add many div elements after clicking on a button. THis div should have input and after clicking on a Save button all input texts inside dynamically created divs should be sent to backend (so I use model inside my template).
<div v-if="!this.spinnerVisibleForCorrectiveActions">
<div>
<table class="p-2 table-cell">
<tr class="font-weight-bold">
<td class="vue-good-table-col-200">
<div class="mt-2 criterion">
ID
</div>
</td>
<td class="vue-good-table-col-200">
<div class="mt-2 criterion">
DZIAŁANIE
</div>
</td>
<td class="vue-good-table-col-200">
<div class="mt-2">
SZCZEGÓŁY
</div>
</td>
</tr>
<tr v-for="(actions,index) in correctiveActions" :key="index">
<td class="vue-good-table-col-200">
<span> {{actions.orderNumber}}</span>
</td>
<td class="vue-good-table-col-200">
<span> {{actions.action}}</span>
</td>
<td class="vue-good-table-col-200">
<span> {{actions.recommendations}}</span>
</td>
</tr>
</table>
<button class="addAction p-3 mb-2 bg-secondary text-white w-100 bg-info btn btn-success">NAdd new action</button>
<br>
</div>
How to add dynamically (multiple times) something like this and additionally to have the possibility to get all data from my dynamically created inputs after clicking on a button:
<tr v-for="(actions,index) in correctiveActions" :key="index">
<td class="vue-good-table-col-200">
<span> {{actions.orderNumber}}</span>
</td>
<td class="vue-good-table-col-200">
<span> {{actions.action}}</span>
</td>
<td class="vue-good-table-col-200">
<span> {{actions.recommendations}}</span>
</td>
</tr>
Ok, the answer in my case is very simple - I have to only add an empty object to my correctiveActions array:
<button class="addAction p-2 mb-2 bg-secondary text-white w-100 bg-info btn btn-success" #click="addNewAction">Nowe
działanie
</button>
and next:
methods:{
addNewAction() {
this.correctiveActions.push
({
id: undefined,
incidentId: this.incidentId,
orderNumber: this.getNextOrderNumber(),
action: undefined,
recommendations: undefined
});
},
}

Xpath to find offset parent in element

I have an automated Selenium test which uses the following XPath
"//tr[td/strong='Riparian 2m Ungrazed - RBS' and td/button[#id='btnDeleteOption_WG']]"
Currently, whenever I query this XPath it returns the element I need but also returns another hidden element which is not on screen.
I have compared the two elements and the only difference is the following
offsetHeight: 39 offsetHeight: 0
offsetLeft: 8 offsetLeft: 0
offsetParent: td offsetParent: null
offsetTop: 10 offsetTop: 0
offsetWidth: 179 offsetWidth: 0
I need to find the element on the left with the offsetParent of <td>.
Can anybody help with an XPath to find this?
Thanks!
Below is the HTML of the element:
<td class="text-center" style="white-space: nowrap;">
<button id="btnShowItems_WG" class="btn btn-sm btn-primary" ng-disabled="!WG_field.optionHasItems" ng-click="WG_field.optionHasItems ? items.visible = !items.visible : false;" title="View Items" disabled="disabled">
<span class="glyphicon glyphicon-list"></span>
</button>
<button ng-hide="!efsEditRole_RoleAssignedToUser" ng-disabled="false" id="btnAddOptionItem_16_WG" class="btn btn-primary btn-sm" ng-click="appSummaryVm.addItem($index, 'WG'); appSummaryVm.addItemsByOption(WG_field.fieldId, WG_field.tranche, WG_field.optionCode, WG_field.optionTypeId, $index, 'WG');"
title="Add Item" aria-hidden="false">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
<td><strong>Riparian 2m Ungrazed - RBS</strong></td>
<td style="width: 10%;">
<input name="optionQuantityWG_16" type="number" class="form-control ng-pristine ng-untouched ng-valid ng-not-empty ng-valid-min ng-valid-max ng-valid-required ng-valid-pattern" ng-class="{
'form-control input-error' : (existingOptionsWG.optionQuantityWG_16.$dirty && (
existingOptionsWG.optionQuantityWG_16.$error.max
|| existingOptionsWG.optionQuantityWG_16.$error.min
|| existingOptionsWG.optionQuantityWG_16.$error.pattern
|| existingOptionsWG.optionQuantityWG_16.$invalid
|| existingOptionsWG.optionQuantityWG_16.$error.required
))
}" ng-change="appSummaryVm.updateOptionTotals(WG_field, 'WG'); appSummaryVm.edit();" ng-model="WG_field.optionQuantity" ng-pattern="/^\d+(\.\d{1,2})?$/" min="" max="" step="0.01" style="text-align: right;" ng-true-value="10.00"
required="" id="optionWGW0316" ng-disabled="!efsEditRole_RoleAssignedToUser" aria-invalid="false">
<div class="form-control inline-errorUp ng-hide" ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && (
existingOptionsWG.optionQuantityWG_16.$error.max
|| existingOptionsWG.optionQuantityWG_16.$error.min
|| existingOptionsWG.optionQuantityWG_16.$error.pattern
|| existingOptionsWG.optionQuantityWG_16.$error.required
|| existingOptionsWG.optionQuantityWG_16.$invalid
)" aria-hidden="true">
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && existingOptionsWG.optionQuantityWG_16.$error.max" aria-hidden="true" class="ng-hide">
maximum of 999999999.99
</span>
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && existingOptionsWG.optionQuantityWG_16.$error.min" aria-hidden="true" class="ng-hide">
cannot be zero or less
</span>
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && (existingOptionsWG.optionQuantityWG_16.$error.pattern || existingOptionsWG.optionQuantityWG_16.$invalid)" ng-hide="existingOptionsWG.optionQuantityWG_16.$error.max || existingOptionsWG.optionQuantityWG_16.$error.min || existingOptionsWG.optionQuantityWG_16.$error.required"
aria-hidden="false" class="">
2 decimal digits only
</span>
<span ng-show="existingOptionsWG.optionQuantityWG_16.$dirty && existingOptionsWG.optionQuantityWG_16.$error.required" aria-hidden="true" class="ng-hide">
required
</span>
</div>
</td>
<td class="text-right">6.00
<!----><span ng-if="WG_field.optionUnitType">/</span>
<!---->m</td>
<td class="text-right">60.00</td>
<td class="text-right">0.70</td>
<td class="text-right">96.00</td>
<td class="text-center">
<button ng-hide="!efsEditRole_RoleAssignedToUser" ng-disabled="false" id="btnDeleteOption_WG" class="btn btn-warning btn-sm" style="width: 110px;" ng-click="appSummaryVm.showRemovePrompt(WG_field, 'option', 'WG', $event); appSummaryVm.edit();" title="Delete 'Riparian 2m Ungrazed' Option from field 3/003/003/3"
aria-hidden="false">
<span class="glyphicon glyphicon-trash"></span> remove option
</button>
</td>
You can get all elements and them filter by visibility. Below is a Java code example, how to get first visible element from list of web elements.
With Java 8:
List<WebElement> elements = driver.findElements(By.xpath("//tr[td/strong='Riparian 2m Ungrazed - RBS' and td/button[#id='btnDeleteOption_WG']]"));
WebElement element = elements
.stream()
.filter(WebElement::isDisplayed)
.collect(Collectors.toList())
.get(0);
Python:
elements = driver.find_elements_by_xpath("//tr[td/strong='Riparian 2m Ungrazed - RBS' and td/button[#id='btnDeleteOption_WG']]")
visible_one = list(filter(lambda x: x.is_displayed(), elements))[0]
visible_one.click()

RobotFramework : How to retrieve the row of an array corresponding to a cell value

In the UI I'm working with, for an object there there is a pencil or a basket icon; I want to click the pencil one (which will trigger an edit modal), and want to do it for the specific object.
For now I use this command line:
Click Element xpath = (//a[#ng-click="openCreateEditModal (holding)"])[2]
I would like to replace the "2" by the value of the line corresponding to the value "RF-Account".
Here is a sample of the HTML:
<tbody ng-if="!isEmpty" class="body-table ng-scope" style="height: 165px;">
<!-- ngRepeat: tenant in tenants track by $index --><tr ng-repeat="tenant in tenants track by $index" class="ng-scope" style="">
<td class="ng-binding">RF-Accou</td>
<td>
<span class="text-bold ng-binding text-muted" ng-class="{'text-green' : tenant.status == 'ACTIVE', 'text-muted' : tenant.status == 'INACTIVE'}">INACTIVE</span>
</td>
<td style="width:118px">
<div class="pull-right">
<a name="editBtn" type="submit" class="btn-icon" ng-click="openCreateEditModal(tenant)">
<span class="icon-i-edit fs" data-toggle="tooltip" title=""></span>
</a>
<a name="deleteBtn" type="submit" class="btn-icon" ng-click="deleteTenant(tenant)">
<span class="icon-i-trash fs" data-toggle="tooltip" title=""></span>
</a>
</div>
</td>
</tr><!-- end ngRepeat: tenant in tenants track by $index --><tr ng-repeat="tenant in tenants track by $index" class="ng-scope">
**<td class="ng-binding">RF-Account</td>**
<td>
<span class="text-bold ng-binding text-muted" ng-class="{'text-green' : tenant.status == 'ACTIVE', 'text-muted' : tenant.status == 'INACTIVE'}">INACTIVE</span>
</td>
<td style="width:118px">
<div class="pull-right">
<a name="editBtn" type="submit" class="btn-icon" ng-click="openCreateEditModal(tenant)">
<span class="icon-i-edit fs" data-toggle="tooltip" title=""></span>
</a>
<a name="deleteBtn" type="submit" class="btn-icon" ng-click="deleteTenant(tenant)">
<span class="icon-i-trash fs" data-toggle="tooltip" title=""></span>
</a>
</div>
</td>
</tr><!-- end ngRepeat: tenant in tenants track by $index --><tr ng-repeat="tenant in tenants track by $index" class="ng-scope">
<td class="ng-binding">RF-Accountfirst</td>
<td>
<span class="text-bold ng-binding text-muted" ng-class="{'text-green' : tenant.status == 'ACTIVE', 'text-muted' : tenant.status == 'INACTIVE'}">INACTIVE</span>
</td>
<td style="width:118px">
<div class="pull-right">
<a name="editBtn" type="submit" class="btn-icon" ng-click="openCreateEditModal(tenant)">
<span class="icon-i-edit fs" data-toggle="tooltip" title=""></span>
</a>
<a name="deleteBtn" type="submit" class="btn-icon" ng-click="deleteTenant(tenant)">
<span class="icon-i-trash fs" data-toggle="tooltip" title=""></span>
</a>
</div>
</td>
</tr><!-- end ngRepeat: tenant in tenants track by $index -->
</tbody>
I am trying to find the line that corresponds to the text value "RF-Account".
For your information, the line of "RF-Account" can change.
Could you please help me find the right keyword to use for Robot Framework ?
To rephrase your question - you need a locator that'll get you that, not a robotframework keyword (the keyword is known, Click Element).
If your anchor is the text, then this xpath will do it for you:
//td[text()="RF-Account"]/following-sibling::td//a[#ng-click="openCreateEditModal(tenant)"]
Let me explain: the first part (//td[text()="RF-Account"]) will select a td element which text is "RF-Account". Then it will look for a follow-up td (the "following-sibling axis), that has an a child with that value for ng-click - and return it (the a).
BTW, in the sample source there is no "openCreateEditModal(holding)", thus I've changed it with "tenant", which is present.
For getting count you can use
Get Matching XPath Count //td[.="RF-Account"]

how to keep bootstrap form button inline

When I put this button in a form it starts a new line but I want it to say inline. I tried adding class="form-inline" but it doesn't work. I must be bad at searching online because I can't find the right answer myself.
What is the bootstrap convention to keep it inline?
<div class="col-sm-12">
<table>
<thead>
<tr>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<a class="inline btn btn-info btn-xs glyphicon glyphicon-pencil"></a>
<button class="form-inline glyphicon glyphicon-trash btn btn-xs btn-danger del" type="button"></button>
</td>
</tr>
</tbody>
</table>
Fiddle
Just alter your markup a little:
Like this demo
<td>
<form class="form-inline" method="POST">
<a class="btn btn-info btn-xs glyphicon glyphicon-pencil"></a>
<button class="glyphicon glyphicon-trash btn btn-xs btn-danger del" type="button"></button>
</form>
</td>

Selenium inside siblings

Is there a way to click further inside siblings in Selenium Webdriver? For example, here's the HTML:
<tr class="rich-table-row xx-datalist-even" onmouseover="Element.addClassName(this, 'xx-datalist-mouseover')" onmouseout="Element.removeClassName(this, 'xx-datalist-mouseover')">
<td class="rich-table-cell xx-datalist " id="userTableForm01:usersTableData:264:j_id102" style="text-align:center; width:20px;">
<img src="/static/images/graphics/status1.gif" title="Disabled" />
</td>
<td id="userTableForm01:usersTableData:264:col1" class="rich-table-cell xx-datalist">
<span id="userTableForm01:usersTableData:264:author_id">2377</span>
</td>
<td id="userTableForm01:usersTableData:264:col2" class="rich-table-cell xx-datalist">seleniumtest2312</td>
<td id="userTableForm01:usersTableData:264:col3" class="rich-table-cell xx-datalist">
<span style="margin-right:3px">Test2312</span>
Selenium
</td>
<td class="rich-table-cell xx-datalist " id="userTableForm01:usersTableData:264:col4" style="text-align:center;">
<input type="checkbox" name="userTableForm01:usersTableData:264:j_id111" onclick="A4J.AJAX.Submit('userTableForm01',event,{'similarityGroupingId':'userTableForm01:usersTableData:264:j_id112','parameters':{'userTableForm01:usersTableData:264:j_id112':'userTableForm01:usersTableData:264:j_id112'} } )" />
</td>
<td id="userTableForm01:usersTableData:264:col6" class="rich-table-cell xx-datalist">
<a id="userTableForm01:usersTableData:264:enable_link" href="#" style="margin-right:5px" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('userTableForm01'),{'userTableForm01:usersTableData:264:enable_link':'userTableForm01:usersTableData:264:enable_link'},'');}return false">
<span id="userTableForm01:usersTableData:264:enable_link_text" class="xx-datalist">Enable</span>
</a>
<a id="userTableForm01:usersTableData:264:edit_link" href="#" style="margin-right:5px" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('userTableForm01'),{'userTableForm01:usersTableData:264:edit_link':'userTableForm01:usersTableData:264:edit_link'},'');}return false">
<span id="userTableForm01:usersTableData:264:edit_link_text" class="xx-datalist">Edit</span>
</a>
<a id="userTableForm01:usersTableData:264:remove_link" href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('userTableForm01'),{'userTableForm01:usersTableData:264:remove_link':'userTableForm01:usersTableData:264:remove_link'},'');}return false">
<span id="userTableForm01:usersTableData:264:remove_link_text" class="xx-datalist">Delete</span>
</a>
</td>
</tr>
Now, this is a much bigger table than shown, so there are a lot more tr's with more users. The ID's are all auto-generated and different each time, and I am trying to click the 'Enable'-link, though the only thing unique on the same row that I can use is the username seleniumtest2312, which has brought me to this:
driver.findElement(By.xpath("//td[text()='seleniumtest2312']/following-sibling::td[3]/span[text()='Enable']")).click();
But it just won't work (no such element).
If there are better ways of solving this issue I'll be happy to try them.
The last part of your XPath is a bit off :
following-sibling::td[3]/span[text()='Enable']
because <span> you're looking for isn't direct child of <td>. You can try this XPath instead :
//td[.='seleniumtest2312']/following-sibling::td[3]/a/span[.='Enable']