Cannot find the nth element on the page using nth-child and WebDriver - css-selectors

I have a form that has 4 calendar Widgets. The html source is the same for all the widgets.
<div class="grid_12">
<td class="wikicell">
<div class="Item">
<div class="Value">
<input type="hidden" id="Submit_Date$_type" value="Date,99/99/9999">
<input id="Submit_Date" size="40" value="" type="text">
<a href="javascript:" class="Calendar">
<img src="transparent.gif" class="Placeholder" tabindex="-1" align="absmiddle">
</a>
</div>
</div>
</td>
I am able to locate the first calendar using the following code:
driver.findElement(By.cssSelector("div.grid_12 img.Placeholder"), 15).click();
But when I try to located the 2nd, 3rd and 4th calendars using nth-child(2)/(3) or (4) I get an "Unable to locate element: {"method":"css selector","selector":"div.grid_12 img.Placeholder:nth-child(2)"}
I also tried with "a.Calendar", "div.grid_12 img" work too for the first calendar. These 3 selectors can successfully click and open the first calendar widget when used with "nth-child(1)" but not for the next 3.
I used Thread.sleep(3000) after the first calendar is closed but I end up getting the same error.
I used findElements() method to get all the calendar widgets and double check using size() to check if the WebDriver is locating all calendar elements. The result is 4 as expected.
Am I not using 'nth-child' correctly?

I first located the form/table that has these calendar icons and called findElement() on this element as a reference to find the respective calendars. Here's the solution -
WebElement form = uiHelper.waitForElementPresent(By.cssSelector("table.left tbody"), 15);
//Enter time
form.findElement(By.cssSelector("tr:nth-child(3) td:nth-child(2) img")).click();
form.findElement(By.cssSelector("tr:nth-child(4) td:nth-child(2) img")).click();

Related

Finding elements in AngularJS using Protractor

I'm writing some automated tests on an AngularJS application. I'm trying to click a button but whatever method I try and use, Selenium refuses to find the element.
<div class="row" _ngcontent-c24="">
<div class="column-12 column-center" _ngcontent-c24="">
<div class="buttons column-center" _ngcontent-c24="">
<div class="buttons-container-centred tablet-up" _ngcontent-c35="">
<div _ngcontent-c35="">
<kf-button _ngcontent-c35="" btnstyle="secondary no-outline btn-big" _nghost-c8="">
<button class="secondary no-outline btn-big" _ngcontent-c8="" title="" type="">
<span _ngcontent-c8="">Use a demo room</span>
</button>
</kf-button>
<span _ngcontent-c35="">Instant access</span>
</div>
This is html around the button - button text is "Use a demo room"
I've tried:
element(by.xpath(" full path from FirePath ").click()
element(by. buttonText("Use a demo room").click()
element(by.xpath('//span[#ngcontent("Use a demo room"]')).click
...to mention a few.
Usual error message stating the element cannot be found once the timeout is reached.
Other similar buttons work fine with a full xpath.
Would be really grateful for advice!
Thanks
David

AngularJS Bootstrap UI Typeahead Not Working Properly with Custom Popup Template

I'm working on a .NET MVC application that has some AngularJS pages in it. I'm trying to use Bootstrap UI Typeahead but it's not quite working properly.
If I start to type in the textbox the autocomplete popup opens with potential matches:
However, if I click on one of the matches nothing happens and the underlying angular model is not updated:
The really strange thing is that if I hit tab while the popup is open the first match will get selected and the angular model is updated appropriately:
This is the template I'm using:
<script type="text/ng-template" id="customTemplate.html">
<div class="search-result search-result--mos ng-scope" ng-if="matches.length > 0">
<ul>
<li ng-repeat="match in matches track by $index" class="search-result__item ng-scope uib-typeahead-match">
<div uib-typeahead-match match="match" index="$index" query="query" ng-bind-html="match.model.value"></div>
</li>
</ul>
</div>
This is the relevant front-end code:
<section class="mos intro" data-ng-controller="MosConverterController as vm">
<div>
<form ng-submit="GetCareers()" class="form form--mos">
<div class="form__row">
<div class="form__col form__col--half-plus">
<label for="MOS" class="form__label">MOS/Rate/Duty Title</label>
<input type="text" ng-model="vm.model.SearchTerm" uib-typeahead="career.value for career in vm.model.CareerResults | filter:$viewValue | limitTo:8" typeahead-popup-template-url="customTemplate.html" id="MOS" class="form__input--text" placeholder="Start Typing" name="MOS" required>
<div>Current Search Term: {{vm.model.SearchTerm}}</div>
<textarea>{{vm.model.CareerResults}}</textarea>
</div>
</div>
</form>
</div>
Here's our angular model. Note that we're using Typescript in this project:
import {MosConverterSearchResult} from "../models";
export class MosConverterModel implements Object {
SearchTerm: string = null;
CareerResults: MosConverterSearchResult[];
SelectedCareer: MosConverterSearchResult;
}
I followed the tutorial from the Angular Bootstrap documentation here for the "Custom popup templates for typeahead's dropdown" section but I can't figure out what I'm doing wrong. I'm sure it's something simple but I just can't figure it out. I should note that adding ng-click to the li element like they have in the tutorial doesn't fix the issue. I've tried it like this before:
<li ng-repeat="match in matches track by $index" class="search-result__item ng-scope uib-typeahead-match" ng-click="selectMatch($index)">
<div uib-typeahead-match match="match" index="$index" query="query" ng-bind-html="match.model.value"></div>
</li>
After banging my head against my desk for a couple of hours I figured out the issue was the ng-if in my template. The example in the tutorial link I posted above uses ng-show. ng-if destroys the DOM element and destroys its scope in the process. That's why nothing would happen when I clicked on an item from the list. Not sure why the tabbing would work though if this was indeed the case. If anyone knows please add a comment or better answer.

AngularJs - apply condition on ng-click

I am making a angularjs app and in this I have a list of users coming fromng-repeat. Now whenever I click on any user a new div box opens. But the problem is that there are multiple boxes opening for the same user and I want only one box for one user.
I tried using ng-if but failed.
I am sharing my code, please check it and provide solutions, thanks in advance.
Code from List of user are coming :
<div class="people">
<div ng-repeat="user in vm.otherUsers | filter : vm.search">
<div directive class="person" ng-click="vm.activateChat(user);bubble=true;" id="chat_{{user.id}}" ng-disabled="true">
<img alt="" />
<span class="name" >{{user.firstName}} {{user.lastName}}
<span ng-if="!bubble && user.counter>0" class="noti_bubble">{{user.counter}}</span>
</span>
</div>
</div>
</div>
and on click activateChat opens the new box for that user.
Code for the box is:
<div ng-repeat="chatUser in vm.multipleUsers">
<div class="msg_box" id="d_{{chatUser.id}}">
--box content--
</div>
</div>
Note: Only one box should open for a single user
You could keep a list of opened boxes per userId in your controller. Then add a function to your controller that you can use in an ng-if or ng-class to show a non-clickable version of your div. Use the same list to check if you should open a new modal in vm.activateChat()

AngularJs open external links in an cordova app

using ng-bind-html in cordova app trying to open external link .
I have installed InAppBrowser plugin
Then i have followed the exact steps from the following
https://gist.github.com/rewonc/e53ad3a9d6ca704d402e
The code with the filter gets executed and the link in it gets changed that is href to window.open code.
But when i click on the link nothing happens.
Anything else i am missing ?
Below is the html that used the ng-bind-html
<div class="card" ng-if="extendedDescription">
<div class="item item-divider">
Ext Description
</div>
<label class="item item-text-wrap">
<span ng-bind-html="extendedDescription">
</span>
</label>
</div>
The span element was wrapped inside the label element because of which none of the events were fired changed
the <label to only contain <span

Show one position of ng-repeat and reload a dropdown each time

So, I'm actually new to angularJS and I've been searching for a while and trying different ways to achieve something, but it seems impossible, to me.
I have this ng-repeat that should show only one of my 6 position array. When I click in "Change", than I should load the second and then the third and so on, until all my data have been accessed and changed by the user, that's why I limited it to 1.
The Professor's select should load according to a parameter from the current ng-repeat class. I have no idea how to solve this problem. I'm trying right now to use a service to load the professor's dropdown, but with no success.
<div class="row" **ng-repeat="class in classes | offset:currentPage | limitTo: 1"** on-finish-render="ngRepeatFinished">
<div style="display: block;">
<div>
<p><label for="">Change:</label> {{ class.professorName }}</p>
</div>
<div>
<p><label for="">By:</label>
<select id="professor" name="professor" class="form-control">
<option ng-repeat="professor in professors" value="{{professor.id}}">{{ professor.name }}</option>
</select>
</p>
</div>
</div>
</div>
<hr>
<center><button type="button" ng-click="change(class.classId)" class="btn btn-primary">Change</button></center>
</div>
What's the best way to achieve something like this (Show only one item each time and after user submits the form, go to the next position... and for each ng-repeat item, I have to reload the professors dropdown)?
Thank you!
Am I understanding you correctly, you want
ng-repeat class in classes //limit 1 //index i.e. [0] +1 change index after button click so you move to the next class index location?
If your setting a value of professor.id in the class or a property that isn't set or is null/undefined before the button, then just add this to your parent div with the loop of class in classes.
ng-if="!class.propName" //if property/dropdown not set
If this isn't what your looking for please expand on your question.

Resources