I am automating an application with selenium.There are no normal labels like id,tag by which I will be able to find an element. So I was using the xpath[driver.findElement(By.xpath())]. But now i find that some of the xpaths of the WebElement changing dynamically while runtime and so my test cases are failing.Even the relative xpath option is not available for the HTML.I am pasting a part of the html of the AUT. Please let me know how to handle this scenario .
<div>
<button class="btn btn-primary ng-hide" ng-click="unlockOrder('/content/boss/en/dashboard');" ng-show="enableUnlockButton" type="button">Unlock Order</button>
<button class="btn btn-primary" ng-click="discardOrder('/content/boss/en/create-order/pre-order-options');" type="button">Discard Order</button>
<button class="btn btn-primary" ng-click="saveOrder(showSaveButton && ban_search.$valid);" ng-disabled="showSaveButton==false || ban_search.$invalid" type="button" disabled="disabled">Save Order</button>
</div>
I would rely on the button text:
driver.findElement(By.xpath('//button[. = "Unlock Order"]'))
where . refers to button's text.
Related
I'm currently stuck trying to click on buttons on a private website. The buttons I'm trying to click have the same attributes and I cannot distinguish which button I need to click. Here are the three buttons I'm trying to click. As you can see, they are similar and except for the text on the button. How can I select for specific button and click it?
<button ng-repeat="punch in $ctrl.nextPunches" ng-disabled="punch.sendingPunch || $ctrl.sendingPunch" type="button" class="btn btn-default ng-binding ng-scope" ng-click="$ctrl.addPunch(punch)" style="">
<!-- ngIf: punch.sendingPunch -->
Check In
</button>
===========================================================================
<button ng-repeat="punch in $ctrl.nextPunches" ng-disabled="punch.sendingPunch || $ctrl.sendingPunch" type="button" class="btn btn-default ng-binding ng-scope" ng-click="$ctrl.addPunch(punch)">
<!-- ngIf: punch.sendingPunch -->
Start Meal
</button>
==========================================================================
<button ng-repeat="punch in $ctrl.nextPunches" ng-disabled="punch.sendingPunch || $ctrl.sendingPunch" type="button" class="btn btn-default ng-binding ng-scope" ng-click="$ctrl.addPunch(punch)">
<!-- ngIf: punch.sendingPunch -->
Check Out
</button>
I have tried using this:
Set HTMLButtons = HTMLDoc.getElementsByTagName("button")
For Each HTMLbutton In HTMLButtons
Debug.Print HTMLbutton.getAttribute("ng-click"), HTMLbutton.getAttribute("type"), HTMLbutton.getAttribute("ng-repeat"), HTMLbutton.getAttribute("ng-disabled")
Next HTMLbutton
HTMLButtons(2).Click
However, the buttons that show up on the immediate window is not helpful and it doesn't click any button when I use the .Click command. These buttons are under the UI element on the webpage. I'm not sure if that is helpful but I can definitely provide more of the webpage code if needed.
Thanks!
You could use document.getElementsByClassName method or document.getElementsByTagName method to get the button (it will return an array), then, loop through this array and distinguish them based on the innerText property. More detail, you could check this article.
Besides, you could also add some custom attributes and set different value, then use it to distinguish them.
I have this bootstrap button group with radio buttons:
<div id="MyField" data-toggle="buttons" class="btn-group">
<label class="btn btn-primary btn-sm"><input type="radio" name="MyField" value="Val1" autocomplete="off">First</label>
<label class="btn btn-primary btn-sm active"><input type="radio" name="MyField" value="Val2" autocomplete="off" checked="">Second</label>
<label class="btn btn-primary btn-sm"><input type="radio" name="MyField" value="Val3" autocomplete="off">Third</label>
<label class="btn btn-primary btn-sm"><input type="radio" name="MyField" value="Val4" autocomplete="off">Fourth</label>
</div>
If I select the value using the mouse, everything works fine. However, if I move to the group using the tab key and select another option using the keyboard arrow keys, the following happens:
The active button changes visually as expected
The change javascript event (handled using jQuery $('#MyField').change(...)) is fired as expected
When the form is submitted, the original value of the default selected radio button is sent to the backend.
Any ideas on why this is and how to fix it?
Turns out this is a bug in bootstrap 3.3.4 which is fixed in 3.3.7. After an update, everything works fine.
My fix was to just include an onfocus attribute to the inputs.
<label class="btn btn-primary btn-sm"><input type="radio" name="MyField" value="Val1" autocomplete="off" onfocus="$(this).click();">First</label>
This is strange. The button is clicked but doesn't redirect to another page.
This is my method :
driver.FindElement(By.XPath("(.//*[normalize-space(text()) and normalize-space(.)='Phone Number'])[1]/following::button[1]")).Click();
or
var Proceed = driver.FindElement(By.XPath("//button[contains(text(),'Proceed')]"));
Proceed.Click();
This how button look in HTML:
<div _ngcontent-c4="" class="col-xs-12 no-padding-sides">
<div _ngcontent-c4="" class="col-xs-8 col-xs-offset-4 no-padding-sides bottom-actions">
<button _ngcontent-c4="" class="btn custom-btn custom-blue" type="submit"> Proceed </button>
<button _ngcontent-c4="" class="btn custom-btn custom-grey" type="button"> Cancel</button></div>
</div>
N.B: I tested the same scenario on selenium IDE and selenium webdriver both have same problem.
Did you try
var Proceed = driver.FindElement(By.XPath("//button[contains(.,'Proceed')]"));
or
var Proceed = driver.FindElement(By.XPath("//button[#class='custom-blue']"));
If those don't work, please post some more HTML.
I am able to select the dropdown and fetch data,but later dropdown is not closing.
Below is my html code for the same:
<clr-dropdown [clrCloseMenuOnItemClick]="true" >
<button type="button" clrDropdownTrigger>
<clr-icon shape="error" class="is-error" size="24"></clr-icon>
<clr-icon shape="caret down"></clr-icon>
</button>
<clr-dropdown-menu *clrIfOpen> <label
class="dropdown-header">Dropdown header</label>
<button type="button" class="dropdown-item "
*ngFor="let module of moduleVal" (click)="selectModuleHandler($event)"
value={{module}}>{{module}}</button>
</clr-dropdown-menu> </clr-dropdown>
I need to close dropdown once work is over,please help me on this.
You should use the Angular component for the dropdown, and then any link you want to autoclose on click you apply the clrDropdownItem directive to the menu items.
https://vmware.github.io/clarity/documentation/v0.11/dropdowns#example
A simple example of About menu on the header:
<div class="header-actions">
<clr-dropdown>
<button class="btn" clrDropdownTrigger>
{{loggedOnUsername}}
<clr-icon shape="caret down"></clr-icon>
</button>
<clr-dropdown-menu clrPosition="bottom-right" *clrIfOpen>
<button type="button" (click)="openUserDialog = true" clrDropdownItem>Manage Users</button>
<button type="button" (click)="openAboutDialog = true" clrDropdownItem>About</button>
<button type="button" (click)="onLogout($event)" clrDropdownItem>Logout</button>
</clr-dropdown-menu>
</clr-dropdown>
</div>
Disclaimers first :
1) First question ever, I hope I'm doing this right, apologies if it's not the case.
2) English is not my native language, so sorry for any mistakes.
3) Made a search and couldn't find an answer.
Trying to explain in words will mean many words while a bootply can say it all :
http://www.bootply.com/EBIMFQ5jEC
Basically, what I want is almost working except for this : I would like that clicking on "title 3" for instance (after you've clicked on "title 1" or "title 2") hides the "first/second column(s)" so that the "third column" is the only one shown (and vice-versa of course). I hope this is clear.
I tried a few things with data-parent (such as this: http://www.bootply.com/pgoT2IPG8D which has data-parent="#collapse1" added for the first three buttons) but couldn't achieve anything...
Thanks in advance for any help !
To get what you want you will indeed have to set the `data-parent', but also notice that this also require a '.panel' class. From the docs:
If a selector is provided, then all collapsible elements under the
specified parent will be closed when this collapsible item is shown.
(similar to traditional accordion behavior - this is dependent on the
panel class)
demo: http://www.bootply.com/qhs4dQbFZK
So you should wrap you collapsible item in a .panel class (or change the plugin). See also: https://github.com/twbs/bootstrap/issues/15341
Then a collapsible item will look that shown below:
<div class="panel">
<div class="col-md-2 collapse" id="collapse1">
<div class="btn-group-vertical btn-block" data-toggle="buttons">
<button class="btn btn-default btn-lg" href="">First subtitle column</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" href="#collapse1-1"><input type="radio" name="subtitle" id="st11">Subtitle 1-1</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" href="#collapse1-2"><input type="radio" name="subtitle" id="st12">Subtitle 1-2</button>
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" href="#collapse1-3"><input type="radio" name="subtitle" id="st13">Subtitle 1-3</button>
</div>
</div>
</div>
Your button should get a data-parent attribute:
<button type="button" class="btn btn-default btn-lg" data-toggle="collapse" data-parent="#menurow" href="#collapse1"><input type="radio" name="title" id="title1">Title 1</button>
And your items should be wrapped inside the id set before (#menurow):
<div class="row" id="menurow"></div>
Notice that the .panel class also set some style rules, which should be overrules (undo) for your situation, for instance: .panel {margin-bottom: 0;}