Issue with identifying object using its ID? - selenium-webdriver

enter image description hereenter image description hereI am working on a Salesforce application and am trying to choose a value from a drop down for my test case but I keep getting a NoSuchElement exception.
I tried to identify the object using its ID
public void enterStep1Details()
{
WebElement element = driver.findElement(By.id("pageid:theform:Block:NewHireRequisitionId:hm:HiringId"));
element.sendKeys("C");
}
Below is the HTML code
<select id="pageid:theform:Block:NewHireRequisitionId:BusinessSegment:selectedReqTypeId" name="pageid:theform:Block:NewHireRequisitionId:BusinessSegment:selectedReqTypeId" size="1" onchange="A4J.AJAX.Submit('pageid:theform',event,{'similarityGroupingId':'pageid:theform:Block:NewHireRequisitionId:BusinessSegment:j_id57','oncomplete':function(request,event,data){RefreshText();},'parameters':{'pageid:theform:Block:NewHireRequisitionId:BusinessSegment:j_id57':'pageid:theform:Block:NewHireRequisitionId:BusinessSegment:j_id57'} } )" style="width:200px">
<option value=""></option>
<option value="Clinical Informatics">Clinical Informatics</option>
<option value="Corporate Services">Corporate Services</option>
<option value="Early Development Services">Early Development Services</option>
<option value="Executive Office">Executive Office</option>
<option value="Late Phase Services">Late Phase Services</option>
<option value="Product Registration">Product Registration</option>
<option value="Strategic Solutions">Strategic Solutions</option>
<option value="Therapeutic Expertise">Therapeutic Expertise</option>
</select>

From what it looks like, it's built from other parts so you will likely need to use the entire ID to be sure that it's unique on the page. You could experiment with AGill's answer but I would just go with the entire ID.
WebElement element = driver.findElement(By.id("pageid:theform:Block:NewHireRequisitionId:BusinessSegment:selectedReqTypeId"));
After talking to the OP some more, turns out the element is in an IFRAME. An example of how to handle this is below.
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
after done in the frame, make sure you switch back to the default content.
driver.switch_to.default_content()
There are other options for accessing IFRAMEs but this should get you started.

You can write a css selector for this. Look for the static portion of the id e.g. look for prefix or suffix or any substring which is unique and static and use that to write the css selector.
For example if id ends with text "selectedReqTypeId" you can write
By.cssSelector("[id$=selectedReqTypeId]")
Also you can write for matching pattern or substring like:
By.cssSelector("[id*='pattern']")
or as per your given code, you can probably write
By.cssSelector("[id*='NewHireRequisitionId']") //just an example
Similarly for startsWith, you can write:
By.cssSelector("[id^=startingText]")

If the element is in a frame you will need to use switchTo() to get into the frame to access the element. You should be able to find lots of reference material on SO for this and elsewhere. – JeffC 21 hours ago

Related

Remove undefined select option after $compile?

It appears that when you create a select element inside of a directive, it creates a sort of dummy option (I assume since at this point it doesn't know what to set it to and doesn't want to make assumptions). The top option below is the option I mean:
<select ng-model="optionVal">
<option value="? undefined:undefined ?"></option>
<option value="opt1">Option One</option>
<option value="opt2">Option Two</option>
</select>
Functionally everything works, but having that empty entry in the select box is ugly, and I'd like to remove it. Does anyone know a way to do that?
That option is created because your model does not contain one of opt1 or opt2, so it creates an option to match the current value of your model. The way to avoid that is to set your model to a value first.

AngularJS select option not displaying in IE 10

We are attempting to resolve a maddening bug in IE 10 in which the option label of the selected option does not get rendered for an Angular <select>. Instead, the label of the option appears as {{option}}, implying that the directive could not be resolved. What is worse is that this problem does not happen in IE 11 or later, or Chrome. Here is the relevant code:
The HTML:
<select class="settings-select-box" name="LOCATION_UPDATE_FREQUENCY"
id="LOCATION_UPDATE_FREQUENCY"
data-ng-model="configurations.LOCATION_UPDATE_FREQUENCY">
<option data-ng-repeat="option in frequency" value="{{option}}">{{option}}</option>
</select>
In the controller JS code we define frequency as a static array, since the choices will never change:
$scope.frequency = ["Never","Daily","Weekly","Monthly"];
The scoped variable used for the model is configurations.LOCATION_UPDATE_FREQUENCY, and is defined using a value from the database. Persisting to the database works on IE 10 and other browsers, which means that binding from the UI to the server appears to be working without issue.
What is really strange about this bug is that the correct option still gets selected in IE 10, but the label is broken or not being rendered properly.
Here is a screen capture to further illustrate the problem:
According to offical documentation you should use "ng-value"
https://docs.angularjs.org/api/ng/directive/ngValue
<select class="settings-select-box" name="LOCATION_UPDATE_FREQUENCY"
id="LOCATION_UPDATE_FREQUENCY"
data-ng-model="configurations.LOCATION_UPDATE_FREQUENCY">
<option data-ng-repeat="option in frequency" ng-value="{{option}}">{{option}} </option>
</select>

What is Angular Directive for pop-up menu please?

I have a web application to write and in the majority of cases I have a 1 to 1 relationship between objects of Class A and objects of Class B, so I hop from one to the other. Sometimes it is 1 to many, in this case I need to display a popup menu and let the user take a selection from the menu and then I will navigate as if it was 1 to 1.
All this is brand new code so no legacy JavaScript/J Query exists.
I seldom write web code but from I have learnt recently Angular appears to be an architectural correct way to do things instead of writing my own JavaScript I want to use the correct Angular method.
But I need a start point. I was looking for a Angular directive and I can see things like input[email] and input[month] but I cannot see input[dropdown] or input[popup].
Can someone please steer me in the right direction? Thanks.
For dropdowns you want to use html-select. To dynamically add values to the dropdown use ng-options with the html select.
<select>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>

Selectpicker : ng-options working with json but <option> not showing anything

I'm trying to display different server's id in a custom selectpicker. The selectpicker works fine if the options tag are "hard coded" but not when I try to retrieve them from a json file (the json is good since the same works with a table in the same page).
Working:
<select id="bs3Select" class="selectpicker show-tick form-control" multiple data-live-search="true">
<option>cow</option>
<option>bull</option>
<option class="get-class" disabled>ox</option>
</select>
Not working:
<select ...ng-model="selected" ng-options="project.idproject as project.idserver for project in projects">
<option value="">-- YON --</option>
</select>
The weird thing is that for each hard-coded option in the second case (like "--YON--" here), when I click it, the server's id corresponding (meaning, if I have two options, the second server id in my json is corresponding to the second option) is displayed in the select!
I tried quite every syntax I have seen on the web but still not working...
Someone has an idea?
I've made a simple plnkr for you http://plnkr.co/edit/2SbSwL05nx5Ta8KevEDC?p=preview
that is working, can you maybe post a sample of that JSON is it object of objects or array of objects?

How to set option value using ng:Options

Apparently AngularJS cannot properly construct a list of <option> elements as a simple template in IE, so it provides the ng:Options directive (see https://github.com/angular/angular.js/issues/235).
After looking at the source, I was able to construct the options with the desired labels, as follows (JSFiddle):
<!-- what I'd like to do -->
<select>
<option ng:repeat='key in keys' value='{{key}}'> {{lookup[key].firstName}} {{lookup[key].lastName}} </option>
</select>
<br/>
<br/>
<!-- what Angular lets me do -->
<select ng-model='key' ng:options='k as lookup[k].firstName + " " + lookup[k].lastName for k in keys'></select>
However, when I inspect the options with Firebug, I see that the value is a numeric index, not my desired key value (I was hoping the initial k would be used as the option value).
I haven't looked deeply into the code, so don't know if there's another part of the expression that I'm missing (the regex doesn't seem to have any additional relevant keywords).
I was hoping that someone here might know this directive well enough to tell me (1) how to do it, or (2) that I'm out of luck.
Your desired key value is in the property you specify by ng-model, i.e., key. Add {{key}} to the bottom of your HTML (just after your last select list) to see it.
As you discovered, Angular stores the array index in the HTML. For more about this, see AngularJS - value attribute for select

Resources