WATIR : how to set a checkbox inside a label - watir

How can I check that checkbox using WATIR
<label title="Active-DC Cloud Management" class="custom-checkbox ng-scope folderSelector">
<span class="customCheckBox icn" ng-disabled="cDisabled">
<input class="ng-pristine ng-valid" ng-model="model" ng-change="changeCallback({$event:$event})" ng-disabled="cDisabled" type="checkbox">
</span> Active-DC Cloud Management<!-- ngIf: cFoldertype == 'ASP' || cFoldertype == 'VCE' || cFoldertype == 'CPL' -->
</label>
I have tried using the following but that doesn't work
#browser.label(:text,'Active-DC Cloud Management').parent.click
Here is more of the HTMl code
<li class="ng-scope" ng-repeat="subfolder in subfolder.subFolders" ng-class="{expandButton:subfolder.hasSubFolders,plus:subfolder.hasSubFolders, disabled:subfolder.folderAccess == 'NONE', selected:selectedFolderIdsArray.indexOf(subfolder.folderId) !== -1}" id="1001665955" ftpath="HOME\Order_12329753" ftname="Order_12329753" ftlevel="2" fttype="ORDER" ftaccess="VIEW">
<a name="&lpos=my : 263" href="javascript:void(0)" ng-click="toggleSelectFolder(subfolder.folderId,subfolder.fullFolderPath)" style="padding-left: 28px" data-this-tree="thisTree" complete-folder-stack="completeFolderStack" folder-data-ftype="subfolder.folderType">
<span class="expandCollapseIcon ng-hide" style="left: 15px" ng-show="subfolder.hasSubFolders" ng-click="expander($event,subfolder.folderAccess); ajaxLoad($event,subfolder)"> </span>
<label class="custom-checkbox ng-scope folderSelector">
<span class="customCheckBox icn" ng-disabled="cDisabled">
<input class="ng-valid ng-dirty" ng-model="model" ng-change="changeCallback({$event:$event})" ng-disabled="cDisabled" type="checkbox"></span>Order_12329753<!-- ngIf: cFoldertype == 'ASP' || cFoldertype == 'VCE' || cFoldertype == 'CPL' --></label></a>
<ul class="subfolder"><!-- ngRepeat: subfolder in subfolder.subFolders --></ul></li>

OK i figured this part out it seems like the div that contains all this code is set to be disabled (not invisible) so because of that I can not use the regular functions associated with the checkbox element but I can use the fire_event method of the browser to click on the checkbox b.input(:xpath,"//label[#title='Active-DC Cloud Management']/span/input").fire_event :click

Related

Selenium with Angular - XPath how to get to elements when $index present?

Using Python 3.7 with Selenium on pages that include Angular, please advise how to best locate an element such as this:
<input type="radio" ng-model="section3.data.generalSection3.container[$index].lseCatTy" value="FEDERAL" ng-disabled="!section3.data.generalSection3.container[$index].editable" ng-class="classes('lseCatTy')" ng-change="section3.updateLseCatTy($index, section3.data.generalSection3.container[$index].lseCatTy)" class="ng-valid ng-not-empty ng-dirty ng-touched ng-valid-parse" name="759" style="">
or this
<button type="button" uib-tooltip="Edit" tooltip-placement="right" class="btn btn-primary" ng-click="section3.data.editContainer($index);" ng-disabled="editingDrilling1 || submissionTypeSR">
when it exists in blocks such as the following. What's tripping me up is the $index... The page has multiple fieldset tags and that number is DYNAMIC... For example, a user can add more of one type of the fieldset while editing the page- but only this one type.
<div ng-if="section3.data.generalSection3.srvyTyId != null && section3.data.generalSection3.srvyTyId != ''" class="ng-scope" style="">
<!-- ngRepeat: wellFeature in section3.data.generalSection3.container track by $index -->
<div ng-repeat="wellFeature in section3.data.generalSection3.container track by $index" class="ng-scope">
<!-- ngIf: section3.data.generalSection3.container[$index].deleteSegmentLocation == null -->
<fieldset class="legend-border ng-scope" ng-if="section3.data.generalSection3.container[$index].deleteSegmentLocation == null">
<legend/>
<div class="col-lg-12 panel panel-default">
<div class="row panel-heading ng-binding">
SHL <br>
<!-- ngIf: section3.data.generalSection3.container[$index].legBHLAttr == 'PPP' -->
<!-- ngIf: section3.data.generalSection3.container[$index].legBHLAttr != 'PPP' && section3.data.generalSection3.container[$index].legBHLAttr != 'SHL' -->
<!-- ngIf: section3.data.generalSection3.container[$index].legBHLAttr == 'SHL' -->
<div ng-if="section3.data.generalSection3.container[$index].legBHLAttr == 'SHL'" class="ng-scope"/>
<!-- end ngIf: section3.data.generalSection3.container[$index].legBHLAttr == 'SHL' -->
</div>
</div>
<div class="row">
<div class="col-lg-11">
<!-- ngIf: section3.data.generalSection3.srvyTyId=='1'|| section3.data.generalSection3.srvyTyId=='3' || section3.data.generalSection3.srvyTyId=='2' || section3.data.generalSection3.srvyTyId=='4' -->
<div ng-if="section3.data.generalSection3.srvyTyId=='1'|| section3.data.generalSection3.srvyTyId=='3' || section3.data.generalSection3.srvyTyId=='2' || section3.data.generalSection3.srvyTyId=='4'" style="padding-left: 15px; padding-right: 15px;" class="ng-scope">
<div class="row">
<div class="col-lg-6">
<div class="form-group">
<label class="required-field">Lease Type</label>
<br>
<div ng-class="classes('lseCatTy'+','+$index.toString(), [])">
<label class="radio-inline">
<input type="radio" ng-model="section3.data.generalSection3.container[$index].lseCatTy" value="FEDERAL" ng-disabled="!section3.data.generalSection3.container[$index].editable" ng-class="classes('lseCatTy')" ng-change="section3.updateLseCatTy($index, section3.data.generalSection3.container[$index].lseCatTy)" class="ng-valid ng-not-empty ng-dirty ng-touched ng-valid-parse" name="759" style=""> Federal
</label>
<label class="radio-inline">
What I have working is:
self.wait.until(EC.presence_of_element_located((By.XPATH, "//button[#ng-click='section3.data.editContainer($index);']"))).click()
And this gets the first instance of that button (in the top fieldset), but I don't know how to get an arbitrary instance of it.
driver.find_elements_by_css_selector('[ng-model*="$index"],[ng-click*="$index"]')
I learned to navigate the DOM using parent elements and finding elements within parent elements --
This became a matter of finding a unique parent (lines 1 and 2), then finding the edit button for that section (line 3), and finding the desired element (line 4).
shl_div = self.wait.until(EC.presence_of_element_located((By.XPATH, "//div[#class='row panel-heading ng-binding' and contains(text(),'SHL')]")))
shl_par = shl_div.find_element_by_xpath("..")
shl_par.find_element_by_xpath(".//button[#ng-click='section3.data.editContainer($index);']").click()
shl_par.find_element_by_xpath(".//input[#value='FEDERAL']").click()

Selenium ClickInterceptedException

I'm trying to click on a button with Selenium on python. The thing is that after I find the element using explicit waits, I get that another elements would recieve the click. I thought that maybe this button had a parent element with the same dimensions and this one was about to get clicked, but it isn't the case. I'm using chromedriver. I'll share the fragment of html code and what I'm doing:
<section id="main">
<div id="form-signin">
<img id="dynamic-logo" src="images/logo.svg" class="height-39px">
<h3 class="clear-margin-bottom margin-top-22px">Sign in</h3>
<div class="form-input margin-top-30px">
<label>
<input id="username" ng-model="data.user" ng-change="checkResetError()" ng-keyup="$event.keyCode == 13 && login()" ng-class="{'has-error': errorMessage !== undefined }" required="" class="ng-pristine ng-untouched ng-invalid ng-invalid-required">
<span class="placeholder">Enter your username</span>
</label>
</div>
<div class="form-input margin-top-30px">
<label>
<input id="password" type="password" ng-model="data.pass" ng-change="checkResetError()" ng-keyup="$event.keyCode == 13 && login()" ng-class="{'has-error': errorMessage !== undefined }" required="" class="ng-pristine ng-untouched ng-invalid ng-invalid-required">
<span class="placeholder">Password
<div class="frd-icon frd-icon-lock pull-right"></div>
</span>
</label>
</div>
<p class="font-xs font-bold fg-red pull-left margin-top-18px ng-binding"></p>
</div>
<button class="btn-frd btn-xl bg-blue btn-block" style="background-color: #00a8e1" type="submit" ng-click="login()">Login</button>
<span class="powered-text" ng-show="isFoundedLogo === true">Powered by Test</span>
And my code for the click part in python is like this:
login_button = WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.ID, "main"))).find_element_by_tag_name("button")
login_button.click()
I don't get why this happens. I also tried to find it by xpath, but the same error appeared.
Thanks

Need help to fill number into Chrome input box with Selenium

Hi I've been trying to fill a number in an input box in Chrome (v 75.0.3770.142) using Selenium Basic ChromeDriver (v 75.0.3770.140) in Excel (2013) VBE
I've tried the below but get error message:
obj.FindElementById("cartPrdQtyBtn0").Value = ("100000")
obj.FindElementByCss("input.form-control.ng-pristine.ng-untouched.ng-
invalid.ng-invalid-required#cartPrdQtyBtn0").SendKeys ("10000")
obj.FindElementByXPath("//input[#class='form-control ng-pristine ng-
untouched ng-invalid ng-invalid-required' and
#id='cartPrdQtyBtn0']").SendKeys ("100000")
(1) HTML before clicking within the input element:
<div class="form-group" ng-class="{'has-error':
(entryItem.invalidProductQuantity || entryItem.invalidPallet ||
entryItem.pumpingQtyError || entryItem.lineItemQtyError)}" ng-
hide="entryItem.isPalletEnabled || entryItem.isCancelled"><!-- ngIf: !entryItem.isDecimal --><input id="cartPrdQtyBtn0" type="text"class="form-control ng-pristine ng-untouched ng-invalid ng-invalid-
required"
restrict="number" restrict-max="100000" required="" ng-
model="entryItem.productDisplayQuantity" ng-
readonly="entryItem.isReadOnly"
ng-blur="updateCartProduct(entryItem, $index)" ng-
if="!entryItem.isDecimal">
<!-- end ngIf: !entryItem.isDecimal -->
<!-- ngIf: entryItem.isDecimal -->
</div>
<p ng-bind="entryItem.productDisplayQuantity" ng-show="entryItem.isCancelled" class="ng-hide"></p>
(2) HTML after clicking within the input element:
<div class="form-group has-error" ng-class="{'has-error':
(entryItem.invalidProductQuantity || entryItem.invalidPallet ||
entryItem.pumpingQtyError || entryItem.lineItemQtyError)}" ng-
hide="entryItem.isPalletEnabled || entryItem.isCancelled">
<!-- ngIf: !entryItem.isDecimal -->
<input id="cartPrdQtyBtn0" type="text"
class="form-control ng-pristine ng-
invalid ng-invalid-required ng-touched" restrict="number" restrict-
max="100000" required="" ng-model="entryItem.productDisplayQuantity" ng-
readonly="entryItem.isReadOnly" ng-blur="updateCartProduct(entryItem,
$index)" ng-if="!entryItem.isDecimal">
<!-- end ngIf: !entryItem.isDecimal -->
<!-- ngIf: entryItem.isDecimal -->
</div>
<p ng-bind="entryItem.productDisplayQuantity" ng-show="entryItem.isCancelled" class="ng-hide"></p>
(3) HTML after sending some text manually (100000):
<div class="form-group" ng-class="{'has-error':
(entryItem.invalidProductQuantity || entryItem.invalidPallet ||
entryItem.pumpingQtyError || entryItem.lineItemQtyError)}" ng-
hide="entryItem.isPalletEnabled || entryItem.isCancelled">
<input id="cartPrdQtyBtn0" type="text" class="form-control ng-pristine
ng-untouched ng-valid ng-valid-required" restrict="number" restrict-
max="100000" required="" ng-model="entryItem.productDisplayQuantity" ng-
readonly="entryItem.isReadOnly" ng-blur="updateCartProduct(entryItem,
$index)" ng-if="!entryItem.isDecimal">
<p ng-bind="entryItem.productDisplayQuantity" ng-show="entryItem.isCancelled" class="ng-hide">100000</p>
To send a character sequence within the input field you can use either of the following Locator Strategies:
cssSelector:
obj.FindElementByCss("input.form-control.ng-pristine.ng-untouched.ng-invalid.ng-invalid-required[id^='cartPrdQtyBtn']").Click
obj.FindElementByCss("input.form-control.ng-pristine.ng-invalid.ng-invalid-required.ng-touched[id^='cartPrdQtyBtn']").SendKeys("10000")
xpath:
obj.FindElementByXPath("//input[#class='form-control ng-pristine ng-untouched ng-invalid ng-invalid-required' and starts-with(#id, 'cartPrdQtyBtn')]").Click
obj.FindElementByXPath("//input[#class='form-control ng-pristine ng-invalid ng-invalid-required ng-touched' and starts-with(#id, 'cartPrdQtyBtn')]").SendKeys("10000")
Note: As it is a dynamic element you need to induce a waiter for the element to be clickable
Reference
You can find a couple of relevant discussions in:
How to send text to some HTML elements?
Trying to fill text in input box with dynamic drop down
finally figured out that it works with the div class also in front:
obj.FindElementByXPath("//div[#class='form-group']/input[#class='form-control ng-pristine ng-untouched ng-invalid ng-invalid-required'and #id= 'cartPrdQtyBtn0']").SendKeys ("100000")

Edge does not show div with Aurelia bindings which I can see in another browsers?

Do you have any idea about this div just disappearing in Edge?
<div
data-filter=".format-${format.id}" class="format cbp-filter-item btn dark btn-outline uppercase"
repeat.for="format of fm.campaignFormats.items | formatsWithDraft"
oa-sortable-item="item.bind: format"
if.bind="(format.just_created && !format.deleted_at) || (!format.deleted_at && format.total_templates)">
<span class="name">${format.name}</span>
<span class="size">${format.width} : ${format.height} [${format.unit}]</span>
<span class="placeholder">${format.name}</span>
<span class="placeholder">${format.width} : ${format.height} [${format.unit}]</span>
<i if.bind="format.loading" class="fa fa-spin fa-circle-o-notch ml-5"></i>
<div class="filter-counter">${format.total_templates}</div>
</div>
I think it's a problem with Aurelia reading data, any ideas?
The issue you encounter is because of attribute reordering in IE & Edge, which in your case will make repeat come after if, which messed up the expression evaluation result. What you can do is to wrap your content in <template/> to separate the attribute:
<template
repeat.for="format of fm.campaignFormats.items | formatsWithDraft">
<div
data-filter=".format-${format.id}"
class="format cbp-filter-item btn dark btn-outline uppercase"
oa-sortable-item="item.bind: format"
if.bind="(format.just_created && !format.deleted_at) || (!format.deleted_at && format.total_templates)">
<span class="name">${format.name}</span>
<span class="size">${format.width} : ${format.height} [${format.unit}]</span>
<span class="placeholder">${format.name}</span>
<span class="placeholder">${format.width} : ${format.height} [${format.unit}]</span>
<i if.bind="format.loading" class="fa fa-spin fa-circle-o-notch ml-5"></i>
<div class="filter-counter">${format.total_templates}</div>
</div>
</template>

How to clear all the md-input fields at once inside a md-form using an external button in Angular 2/2+/4

I want to clear all the fields inside a md-form at once using an external clear button like you do in normal HTML Forms. The problem with md-form is that it contains md-input fields instead of regular input fields. So the simple reset function won't trigger that.
I've set the type of each field to 'search' that gives some kind of control but it's like u have to manually click and remove each value of the filed. I want to erase them all at once.
Is there a proper way to to this?
Thanks in advance.
Form Code
<form class="formwidth" (ngSubmit)="searchClass()" #myForm="ngForm">
<table class="fullwidth" cellspacing="0">
<tr>
<td>
</td>
<td>
<md-input-container div="addClassName" *ngIf="classClicked === true">
<input [(ngModel)]="message.className" mdInput placeholder="Class Name" id="className" name="classname" type="search" >
</md-input-container>
<md-input-container div="addJarName" *ngIf="jarFileClicked === true">
<input [(ngModel)]="message.jarName" mdInput placeholder="Jar File Name" id="jarName" name="jarname" type="search" >
</md-input-container>
<md-input-container div="addVersion" *ngIf="versionClicked === true">
<input [(ngModel)]="message.version" mdInput placeholder="Version" id="versionNumber" name="versionnumber" type="search" >
</md-input-container>
<md-input-container div="addDirectory" *ngIf="directoryClicked === true">
<input [(ngModel)]="message.directory" mdInput placeholder="Directory" id="directoryName" name="directoryname" type="search" >
</md-input-container>
<md-input-container div="addDependentClass" *ngIf="dependentClicked === true">
<input [(ngModel)]="message.dependentClass" mdInput placeholder="Dependent Class Name" id="dependentClassName" name="dependentclassname" type="search" >
</md-input-container>
</td>
</table>
<br>
<p *ngIf="classClicked === true || jarFileClicked === true || versionClicked === true || directoryClicked === true || dependentClicked === true">
<button md-raised-button color="accent" type="submit" id="submitButton">Submit</button>
<button md-raised-button id="clearButton" (click)="setAllToFalse() && clearFields()">Clear</button>
</p>
</form>
P.S : I tried something like this with typescript as well. But it don't work
clearFields(){
this.message.jarName="";
this.message.className="";
this.message.version="";
this.message.directory="";
this.message.dependentClass="";
}
Simply calling the clearFields() method inside another method worked.
setAllToFalse(){
this.classClicked = false;
this.jarFileClicked = false;
this.versionClicked = false;
this.directoryClicked = false;
this.dependentClicked = false;
this.condition_1 = false;
this.condition_2 = false;
this.condition_3 = false;
this.condition_4 = false;
this.condition_5 = false;
this.condition_6 = false;
this.condition_7 = false;
this.clearFields();
}

Resources