Pyppeteer / puppeteer / Angular JS selection of radio button doesn't work - javascript

I have a div function which has a radio button which I would like to select 'fire' using Pyppeteer. However, when I try to do this, all attempts I try fail
Div
<div _ngcontent-xqm-c396="" class="ng-star-inserted">
<p-radiobutton _ngcontent-xqm-c396="" styleclass="radio-group__input" name="APPLICANT_TYPE" class="ng-untouched ng-valid ng-dirty">
<div class="radio-group__input ui-radiobutton ui-widget">
<div class="ui-helper-hidden-accessible">
<input type="radio" name="APPLICANT_TYPE" value="Corporate">
</div>
<div role="radio" aria-checked="true" class="ui-radiobutton-box ui-widget ui-state-default ui-state-active">
<span class="ui-radiobutton-icon ui-clickable pi pi-circle-on">
</span>
</div>
</div>
<label class="ng-star-inserted ui-radiobutton-label ui-label-active">Corporate</label>
<!---->
</p-radiobutton><validationmsg _ngcontent-xqm-c396="" _nghost-xqm-c395="" hidden="">
<!---->
</validationmsg>
</div>
The pyppeteer command I use
await page.click("input[name='APPLICANT_TYPE']")
This is the XPATH:
//*[#id="lead_request_main_ui_applicant_type"]/div[2]/p-radiobutton/div/div[1]/input
This is the JS PATH
document.querySelector("#lead_request_main_ui_applicant_type > div:nth-child(3) > p-radiobutton > div > div.ui-helper-hidden-accessible > input[type=radio]")
If either of those help you? I've been trying this for the past 2 days and I have had no success :-(

In the end this looks like a bug with Pyppeteer
To get around it, I had to do this workaround which now works:
foo = await page.querySelector('[value="Corporate"]') # or any proper selector
await page.evaluate('(element) => element.click()', foo)
Will probably save you about 4 days of effort!

Related

Angular JS dynamically set tabindex attribute

I'm fairly new to Angular, and I'm working on a simple flashcard website. Here's my current relevant HTML:
<div id="flashcards" class="row">
<div class="flashcard col-sm-6 col-md-4 col-lg-3"
ng-repeat="card in cards">
<div class="flashcard-inside"
ng-class="{'flipped' : card.flipped}">
<div class="flashcard-btns">
<button ng-click="flip(card)" class="btn btn-secondary">
<i class="fas fa-sync-alt"></i>
</button>
<button ng-click="remove(card)" class="btn btn-danger">
<i class="fas fa-trash"></i>
</button>
</div>
<div class="flashcard-front">
<textarea ng-model="card.front"
class="form-control
flashcard-content"
ng-tabindex="{-1 : card.flipped}">
</textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back"
class="form-control flashcard-content"
tabindex="card.flipped ? 0 : -1">
</textarea>
</div>
</div>
</div>
</div>
I'm making a flashcard for each card in cards.
My remove and flip functions are fairly simple:
$scope.flip = (card) =>
card.flipped = !card.flipped;
$scope.remove = (card)=>
$scope.cards = $scope.cards.filter(obj=> obj.front!=card.front || obj.back!=card.back);
As you can see above, I've tried ng-tabindex="{-1 : card.flipped}" and I've tried tabindex="card.flipped ? 0 : -1" and several other combinations with no luck. I was hoping someone more experienced in Angular could point me in the right direction. It seems my problems would be solved if I could get a hold of the DOM element from the card variable in my flip scrips, and set its tabindex attribute with jQuery, however I can't seem to access the element for the textarea (which would be nice because I'd also like to focus it later).
There is no need to use ng-attr-tabindex, it can simply be done with interpolation:
<div class="flashcard-front">
<textarea ng-model="card.front" class="form-control flashcard-content"
tabindex="{{card.flipped ? -1 : 0}}"></textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back" class="form-control flashcard-content"
tabindex="{{!card.flipped ? -1 : 0}}"></textarea>
</div>
The problem with the code in the question is that the interpolation needs double curly brackets ({{ }}).
The ng-attr-* syntax is only necessary in exotic situations.
For more information, see
AngularJS Developer Guide - Interpolation
AngularJS Developer Guide - ngAttr for binding to arbitrary attributes
Credit to #Phix for the suggestion to use ng-attr.
The relevant part is ng-attr-tabindex="{{card.flipped ? -1 : 0}}" and the same but with !card.flipped instead of card.flipped.
My full code is:
<div class="flashcard-front">
<textarea ng-model="card.front" class="form-control flashcard-content"
ng-attr-tabindex="{{card.flipped ? -1 : 0}}"></textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back" class="form-control flashcard-content"
ng-attr-tabindex="{{!card.flipped ? -1 : 0}}"></textarea>
</div>
Angular Docs

Protractor : Selection of an element from Popup value

We have some textboxes where the value needs to be selected from a popup list. The elements and the popup are like this:
The related html codes are as follows:
<div _ngcontent-c6="" class="col px-0">
<input _ngcontent-c6="" aria-multiline="false" autocapitalize="off"
autocorrect="off" class="form-control ng-dirty ng-valid open ng-touched"
formcontrolname="ESYSITENAME" id="esySiteName" name="" placeholder=""
role="combobox" type="text" autocomplete="off" aria-autocomplete="list"
aria-expanded="true" aria-activedescendant="ngb-typeahead-2-0"
aria-owns="ngb-typeahead-2">
<ngb-typeahead-window class="dropdown-menu show ng-star-inserted"
role="listbox" id="ngb-typeahead-2" style="top: 39px; left: 0px;">
<button class="dropdown-item ng-star-inserted active" role="option"
type="button" id="ngb-typeahead-2-0">
<ngb-highlight _ngcontent-c6="" _nghost-c25="" class="ng-star-inserted">
<span _ngcontent-c25="" class="ngb-highlight ng-star-inserted">
Bull Run Elementary School
</span>
</ngb-highlight>
</button>
</ngb-typeahead-window>
</div>
I have tried to select the Popup element using different strategies like:
let EsyNamePopup = $('#ngb-typeahead-2-0 > ngb-highlight > span');
await helpers.waitForElementVisibility(EsyNamePopup);
await helpers.clickWhenClickable(EsyNamePopup);
// or following way:
let EsyNamePopup = element(by.cssContainingText('span', 'Bull Run Elementary School,));
await EsyNamePopup.click();
None of them worked but got following error messages:
NoSuchElementError: No element found using locator: By(css selector, #ngb-typeahead-2-0 > ngb-highlight > span)
Is there a better strategy to select these elements?
I think you can try a long sleep before click on the pop option. If long sleep can fix your issue, it proves your wait function waitForElementVisibility has issue or you not give sufficient wait time.
await $('input#esySiteName').sendKeys('Bull');
await browser.sleep(15000)
await $('#ngb-typeahead-2-0 > ngb-highlight > span').click()
You could set up breakpoints and debug your code by following the steps in here.
http://www.protractortest.org/#/debugging
Might want to verify if sendkeys will initiate the typeahead popup or if element needs to be focused in order for that.

How to hide "div" from js, which use information from spring?

In my website, on UI I show information from DB, use "spring". I want to make, if items quantity equals 0, then I hide this "div". If items quantity more than 0, then I show "div"
In html I recive from spring:
<div th:each="viewAvailableWhisky : ${viewAvailableWhisky}">
<div class="tilt pic" id="ShowHide">
<a th:href="#{~/buySelectedWhisky(nameBuyWhiskey=${viewAvailableWhisky.id})}" >
<img th:attr="src=${viewAvailableWhisky.photo}" id="photoId" width="150" height="250"/>
<div>
<b> <span th:text="${viewAvailableWhisky.nameWhisky}">Name</span></b>
</div>
<div>
<b> Quantity: <span th:text="${viewAvailableWhisky.quantityWhisky}"
>quantityWhisky</span>piece</b>
<input type="hidden" id="quantity" th:value="${viewAvailableWhisky.quantityWhisky}"/>
</div>
<div>
<b> $ <span th:text="${viewAvailableWhisky.price}">Price</span></b>
</div>
</a>
</div>
</div>
I think, it's better to make the with use a JS. But I don't understand how, I try use this code. This code can't catch
quantity of goods of each item from a DB
$(document).ready ( function(){
var quantityItems = $("#quantity").val();
console.log(quantityItems);
if(quantityItems>0){
$("#ShowHide").show();
}
else {
$("#ShowHide").hide();
}
});
The th:if="${condition}" attribute is used to display a section of the view if the condition is met.
<span th:if="${student.gender} == 'M'" th:text="Male" />
Furthemore, thymeleaf offers option to display certain section if given condition is NOT met using th:unless
<span th:unless="${student.gender} == 'M'" th:text="Female" />
(For further info see This tutorial or this intro to Thymeleaf conditionals)
To display certain content only if user has specific role, use spring security's integration with thymeleaf.
<div sec:authorize="hasRole('ROLE_ADMIN')">
This content is only shown to administrators.
</div>
More info about Spring Security integration here.

kibana 4 search place out of iframe

kibana 4 search code looks like following
<form name="queryInput" class="fill inline-form ng-valid ng-dirty" ng-submit="filterResults()">
<div class="typeahead ng-isolate-scope" kbn-typeahead="dashboard">
<div class="input-group" ng-class="queryInput.$invalid ? 'has-error' : ''">
<input input-focus="" placeholder="Filter..." class="form-control ng-isolate-scope ng-valid ng-valid-query-input ng-dirty" ng-model="state.query" kbn-typeahead-input="" validate-query="" type="text"><i style="display: none;" class="fa fa-ban input-error"></i>
<button type="submit" class="btn btn-default" ng-disabled="queryInput.$invalid">
<span class="fa fa-search"></span>
</button>
</div>
<div ng-show="typeahead.isVisible()" ng-mouseenter="typeahead.setMouseover(true);" ng-mouseleave="typeahead.setMouseover(false);" class="typeahead-items ng-hide">
<!-- ngRepeat: item in typeahead.getItems() --><div ng-repeat="item in typeahead.getItems()" ng-class="{active: item === typeahead.active}" ng-click="typeahead.selectItem(item, $event);" ng-mouseenter="typeahead.activateItem(item);" class="typeahead-item ng-binding ng-scope">
*
</div><!-- end ngRepeat: item in typeahead.getItems() -->
</div>
</div>
</form>
I have kibana dashboard in iframe in my page.
I want to have following code out of that iframe and want it to have functionality same as above code.
<input id="logsSearch" name="logsSearch" type="text"/>
to achieve this i have tried following options.
'keypress #logsSearch' : function(e){
if (e.keyCode == 13) {
var strSearch = $("#logsSearch").val();
$("#kibana").contents().find('form[name=queryInput]').find('input').val(strSearch);
var e = jQuery.Event("keydown");
e.which = 13; // # Some key code value
$("#kibana").contents().find('form[name=queryInput]').find('input').trigger(e);
$("#kibana").contents().find('form[name=queryInput]').find('button').click();
}
}
but it doesn't work. it calls /kibana4/elasticsearch/_msearch
but it doesn't call __kibanaQueryValidator.
in other solution i tried to trigger keyup, keydown events as well. but it also doesn't work
I don't know how should I do it. Any ideas or pointers or guidance to solve this problem will be a great help.

Not able to select a dropdown using webdriver

I'm using http://www.makemytrip.com/
The below is the Html code.
<div class="mrgnBot30 clearFix">
<span class="watch_icn flL"></span>
<div class="widget_inner clearFix suggest_me padBot15 flL">
<h3 class="clearFix hasBorderBottom">
<p class="clearFix checkDates">
<span class="check_date flL">
<label for="checkInDate">
Check-in Date:
<span id="checkInDate_day" class="dayLight">(Monday)</span>
</label>
<a id="checkInDateControl" class="cal_icn flL" href="#" tabindex="201"></a>
<input id="checkInDate" class="day flL hasDatepicker" type="text" autocomplete="false" value="01/21/2013" name="searchCriteria.criterion.stayDateRanges[0].start" style="display: none;">
<span class="day date flL">
<select class="selectBox" tabindex="202" style="display: none;">
<span class="left_part flL"></span>
<span class="selectBox center_part flL selectBox-dropdown" style="display: inline-block; -moz-user-select: none;" title="" tabindex="202">
<span class="selectBox-label">21</span>
<span class="selectBox-arrow controls flR">
<a class="select_drop_icon flR" onclick="return false;" href="#"></a>
</span>
</span>
<span class="right_part flL"></span>
</span>
<span class="day month flL">
<select class="selectBox" tabindex="203" style="display: none;">
<span class="left_part flL"></span>
<span class="selectBox center_part flL selectBox-dropdown" style="display: inline-block; -moz-user-select: none;" title="" tabindex="203">
<span class="selectBox-label">Jan,13</span>
<span class="selectBox-arrow controls flR">
<a class="select_drop_icon flR" onclick="return false;" href="#"></a>
</span>
</span>
<span class="right_part flL"></span>
</span>
</span>
<span class="check_date last flL">
<span id="nights" class="nights flL">2 Night(s)</span>
</p>
</div>
</div>
Here i'm having a dropdown to select a Check in date and Check out date. Frankly say, i don't know how to select a value of the dropdown from code. Moreover i am not sure weather it is a dropdown or not. why i am saying mean while recording in selenium IDE it records as click event for selecting a value from the dropdown.
I tried select statement to select a value from dropdown by catching a xpath value using firebug.
The used code:
driver.get("http://www.makemytrip.com/");
driver.findElement(By.xpath("//li[4]/a/span/span")).click();
Select sel = new Select(driver.findElement(By
.xpath("//div[2]/div/p/span/span/span[2]")));
try {
sel.selectByValue("21");
} catch (Exception e) {
e.printStackTrace();
}
Nothing works. Below is the converted code from selenium IDE after the recording.
Selenese Code:
driver.get("http://www.makemytrip.com/");
driver.findElement(By.xpath("//div[#id='chf_navigation']/ul/li[4]/a/span/span")).click();
assertEquals("I want to go to", driver.findElement(By.cssSelector("label")).getText());
assertEquals("Online Hotel Booking for Cheap, Budget & Luxury Hotels in India | MakeMyTrip.com", driver.getTitle());
driver.findElement(By.xpath("(//a[#onclick='return false;'])[2]")).click();
driver.findElement(By.xpath("(//a[#onclick='return false;'])[3]")).click();
driver.findElement(By.xpath("(//a[#onclick='return false;'])[4]")).click();
driver.findElement(By.cssSelector("li.selectBox-hover.selectBox-selected > a")).click();
driver.findElement(By.xpath("(//a[#onclick='return false;'])[5]")).click();
Steps to see the dropdown:
Open http://www.makemytrip.com/
Click Hotels link
U able to see Check in Date dropdown.
Please provide useful suggestions to resolve the problem. Thanks in advance.
You have given the html code but u have not provided us the code which u have written, please provide the code u have written for this program and also let us know the error message or exception displayed.
Check in date select ids are b_checkin_day && b_checkin_month. Here is how to select them
//select the check-in date <select> element
Element el = driver.findElement(By.id('b_checkin_day'));
Select sel = new Select(el)
// go on with selection
Ckeck out select id are : b_checkout_day && b_checkout_month
That's for the US version. Indian version is definitly not a select but does not correspond to your html
EDIT : found that you were talking about Emirates website.
Sor for the day select, you should go with :
Element el = driver.findElement(By.xpath("//input[#id='checkInDate']/following-sibling::span[contains(#class,'date')]/select"))
xpaths are the following for month checkIn, day Checkout && month checkout respectively
"//input[#id='checkInDate']/following-sibling::span[contains(#class,'month')]/select"
"//input[#id='checkOutDate']/following-sibling::span[contains(#class,'day')]/select"
"//input[#id='checkOutDate']/following-sibling::span[contains(#class,'month')]/select"
Your first solution is to use these xpath to select the correct values
You can also more simply check the correct date in the inputs that are used to fill the form
i.e setting the correct date as value in
<input id="checkInDate" class="day flL hasDatepicker" type="text" autocomplete="false" value="01/21/2013" name="searchCriteria.criterion.stayDateRanges[0].start" style="display: none;">
should do the trick. (note the value="01/21/2013")
EDIT2 :
Have you tried to do that with the actual elements used by the visitor ? First, click on the dropdown arrow ("//input[#id='checkInDate']/following-sibling::span[contains(#class,'date')]/"), it will make the select used by the javascript date selector visible.
You then should be able to make the good selection when clicking on :
//ul[contains(#class,'selectBox-dropdown') and contains(#style,'block')]//a[#rel="25"]
if 25 is the day you want. <ul>s/<li>s that are used to make the selection are at the bottom of the page. Look at them, you'll find the correct xpath

Categories

Resources