Selenium XPath not found for IEDriver when I add URL/Domain in compatibility view - selenium

When I execute my script using IEDriver without compatibility view, my test script is running without any problem.
But, If I execute the same script after adding domain in compatibility view, then some elements are not found and I'm getting exceptions.
e.g.
I want to get text of selected item from this DOM:
<select id="selectNumber" name="selectNumber" style="width:180px;">
<option selected="selected" value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
and I'm using XPath .//*[#id='selectNumber']/option[#selected='selected']
to get text but it does not work.
I just checked that in IE DOM selected="selected" is not displayed for selected option until I change Document version manually.

You can use the Select class that works with every browser. Here's some code
Select sel = new Select(driver.findElement(By.id("selectNumber")));
WebElement selectOption = sel.getFirstSelectedOption();
String text = selectOption.getText();

I think you should consider to change from using XPath to use cssSelector. It's much safer to find the elements, not depending on the whole "path". There's a big chance it would not break when using cssSelector running with IEDriver (as you stated in your question).
You can achieve the same goal with both, but when you use XPath, your DOM is much more sensible to changes, and you have bigger chances to see tests broken after page changes.
For your case, you could use it in two ways:
XPath (as you must have it)
driver.findElement(By.xpath(".//*[#id='selectNumber']/option[#selected='selected']"))
Selector
driver.findElement(By.cssSelector("#selectNumber[selected]"))
When you have more complex "paths" you can combine more things like CSS classes in cssSelectors. For example (when you don't have ID):
<select class"nice-dropdown" name="selectNumber" style="width:180px;">
<option selected="selected" value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
driver.findElement(By.cssSelector("select.nice-dropdown")) (return the select element)
driver.findElement(By.cssSelector("select.nice-dropdown option[value='3']")) (return the option with value=3)
With selectors you have shorter "paths". They work in the same way as selectors are used in CSS.
As reference:
Selectors = w3schools
Selectors = W3C
Hope this information is somehow helpful.

Related

How to have nested select dropdown that will fetch differently for the main list and the dependent list for htmx?

Was requested by maintainer to repost here
Issue
In https://htmx.org/examples/value-select/
I can tell that the make is directly in the html and when it changes, the hx-get is called to fetch a new list of models.
What if I want to have both the make and the model all rely on ajax?
meaning to say
<select name="makes" id="makes" hx-get="/makes" hx-trigger="load">
<option value="none">original</option>
</select>
<select name="models" id="models">
<option value="none">original</option>
</select>
i like to be able to fetch from /makes on load to get the list of makes option
and then somehow I can also fill up the dependent models as well.
I don't mind doing it as two requests. The reason is that in my situation the makes are also dependent on a 3rd party API
I hope I understand what you want, but something like this should work:
<select name="makes" id="makes" hx-get="/makes" hx-trigger="load">
<option value="none">original</option>
</select>
<select name="models" id="models"
hx-get="/models"
hx-trigger="changed from:#makes"
hx-include="#makes">
<option value="none">original</option>
</select>
So you add a trigger to the second drop down that listens for changed events on the #makes drop down and then fires up a request to the /models URL, including the value of the #makes drop down so you know what models to return.
Does that seem like what you want?

Angular not compatible with chrome

I have a dropdown list with two links in angular. it is working with firefox and not working with chrome. is there any compatible issues for angular with chrome?
<div id="SelectField">
<select class="form-control form-control-lg">
<option value="" selected disabled>Select to Deploy Product/Products</option>
<option (click)="Single()">Deploy Single Product</option>
<option (click)="Multiple()">Deploy Multiple Products</option>
</select>
</div>
It is working fine with firefox but in chrome its not activating when we select an option
You can use change event in select tag and set the value of first option as undefined and rest of the options with any string value inside [ngValue]="single".
Here single is a string value which is assigned to that option.
You have to check in the change event with if condition what is passed as a value based on that you can call your respective methods..
Make sure you have to use ngModel in the select and ngValue will be your selected option value

Dynamic XPath- Selenium

I have the following dynamic xpath:
/html/body[#class='modal-open']/div[#class='container']/form[#id='form_application']/div[#id='interviewContent']/div[#class='modal-dialog']/div[#class='modal-content']/div[#class='modal-body']/div[#id='form_application:interviewContent']/div[#id='form_application:questionDropdown']/select[#id='form_application:j_idt473']
How can I make this unique for Selenium Web Driver? I was going to do a Starts-with method but this is pertaining to a drop down box where the values selected changes with each log in.
Page Source:
<br /><select id="form_application:j_idt473" name="form_application:j_idt473" class="form-control" size="1" style="width:250px;display:inline" onchange="mojarra.ab(this,event,'change','#this','form_application:questionDropdown form_application:dropdown_interview')"> <option value=""></option>
<option value="02">Alaska</option>
<option value="01">Alabama</option>
<option value="05">Arkansas</option>
<option value="60">American Samoa</option>
<option value="04" selected="selected">Arizona</option>
<option value="06">California</option>
""""
You can use css attribute selectors to match partial strings. I would get rid of that super complex xpath and use a contains selector instead to match a substring. Something like this should do the trick...
select[onchange*="form_application:questionDropdown form_application:dropdown_interview"]
As you mentioned in your Question that the xpath is dynamic and the HTML clearly shows the element as a <select> tag so we have to construct our xpath accordingly. I think you were quite right when you spoke about using Starts-with method as looking at the id and name attributes it seems to me though the attributes are dynamic but the string form_application: will be a constant. So we can use the following xpath :
Java
Select city = new Select(driver.findElement(By.xpath("//select[#class='form-control' and starts-with(#id,'form_application:')]")));
city.selectByIndex(2);
Python
select = Select(driver.find_element_by_xpath("//select[#class='form-control' and starts-with(#id,'form_application:')]"))
select.select_by_visible_text("Alabama")

Creating an xpath with a dynamic id

I am having difficulty creating an xpath. I can write an xpath and map it directly to the id and it works fine. The problem arises when I need to select a different product. Most of the id is static and does not change, but the rest of it does change. I've tried writing an xpath with the contains clause and it still does not work.
Here is what I have tried:
//*[contains(#id, 'j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:0:j_id138:j_id139:1:j_id219')]
//*[#id='j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:']/option[5]
Here is the code I'm writing the xpath from:
<select id="j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:0:j_id138:j_id139:0:j_id222" name="j_id0:j_id1:j_id6:section2:j_id34:j_id35:j_id67:j_id68:0:j_id138:j_id139:0:j_id222" class="user-success">
<option value="">--None--</option>
<option value="Budget">Budget</option>
<option value="Drop/New">Drop/New</option>
<option value="Management Change">Management Change</option>
<option value="Never Fulfilled">Never Fulfilled</option>
<option value="Product Swap">Product Swap</option><option value="Renewal">Renewal</option><option value="Stacked">Stacked</option></select>
Try using following:
//div[#class='user-success']/option[5]
This way you don't have to worry about changing xpath.

Selenium 3.0.1 with geckodriver 0.11.1 can't find correct option for select control

I just upgraded some functional testing code to use a newer version of Selenium and the required geckodriver, and now code that previously was selecting an option in an HTML select control is no longer working. I can reproduce the problem with a trivial page:
Here's the relevant code:
1. my_select = Select(driver.find_element_by_id("foo_select"))
2. my_select.select_by_value("3")
and the relevant HTML
<form>
<select id="foo_select" name="foo_select">
<option selected="selected" value="1">Ford</option>
<option value="2">Hyundai</option>
<option value="3">Jeep</option>
<option value="4">Kia</option>
<option value="5">Nissan</option>
<option value="6">Toyota</option>
</select>
</form>
I can check the value of my_select after 1 above and it does indeed refer to the select named "foo_select". But line 2 doesn't seem to be selecting the option with value "3" (it's not selecting anything. I've also tried the other "select_by.." variations). Indeed, if I look at my_select.first_selected_option (after 2) it still refers to the first option, "Ford".
The problem goes away when using Firefox 49. I was using 48.