Selenium select not working on some objects - c#

I am having trouble with setting a Select object through Selenium. This Select object has some JavaScript associated with it that populates it's 'options' when the page is loaded. I believe this is causing it to behave differently. Normally I can set a Select object with the following:
SelectElement sel = new SelectElement(ele);
sel.SelectByText(value);
With this specific object, the same code will execute successfully (no exceptions thrown), however the value does not get set. Note that I put sleeps and re-trys in and I am confident the Select object is fully loaded before the code is executed (otherwise an exception would occur).
The two Select objects giving me this trouble also appear different from standard html Select objects which reinforces my belief that they are not standard Selects. The first two drop downs in this image are the troublesome ones, while the rest work as expected:
Unfortunately this is a private page that I cannot give you access to, but hopefully this HTML snippet is enough:
<h3>Details of your primary qualification, examination, or assessment</h3>
<script type="text/javascript" src="/assets/js/jquery.ui.widget.js"></script>
<script type="text/javascript" src="/assets/js/jquery.ui.position.js"></script>
<script type="text/javascript" src="/assets/js/jquery.ui.selectmenu.js"></script>
<script type="text/javascript">
j$(document).ready(function () {
j$(".field [id$='_drpInstitution']").selectmenu();
j$(".field [id$='_drpName']").selectmenu();
j$(".field [id$='_drpInstitution']").change(function () {
__doPostBack('content_0$ucCourse$drpInstitution', '');
});
j$(".field [id$='_drpName']").change(function () {
__doPostBack('content_0$ucCourse$drpName', '');
});
});
</script>
<div class="field">
<label for="content_0_ucCourse_drpInstitution" id="content_0_ucCourse_lblInstitution">Name of Australian institution (university/college/examining body):<em class="required">*</em></label>
<select name="content_0$ucCourse$drpInstitution" id="content_0_ucCourse_drpInstitution" class="field-l Institution">
<option value="-1">- Select -</option>
<option selected="selected" value="Australian Catholic University">Australian Catholic University</option>
<option value="Avondale College of Higher Education">Avondale College of Higher Education</option>
<option value="Central Queensland University">Central Queensland University</option>
<option value="Charles Darwin University">Charles Darwin University</option>
<option value="Other">- Other -</option>
</select>
<em class="hint">If your institution does not appear in the list, please select 'Other' and enter your institution in the text box that appears.</em>
<span id="content_0_ucCourse_vldInstitution" style="display:none;"></span>
</div>
When I inspect the Dropdown box, instead of getting the Select object I get the following Span:
<span>
<a class="ui-selectmenu ui-widget ui-state-default ui-selectmenu-dropdown ui-state-active ui-corner-top" id="content_0_ucCourse_drpInstitution-button" role="button" href="#nogo" tabindex="0" aria-haspopup="true" aria-owns="content_0_ucCourse_drpInstitution-menu" style="width: 460px;" aria-disabled="false">
<span class="ui-selectmenu-status">Australian Catholic University</span>
<span class="ui-selectmenu-icon ui-icon ui-icon-triangle-1-s"></span>
</a>
</span>
When I inspect the resulting drop down list, I get a UL located in the footer:
<div class="ui-selectmenu-menu" style="z-index: 2; top: 786px; left: 741px;">
<ul class="ui-widget ui-widget-content ui-selectmenu-menu-dropdown ui-corner-bottom" aria-hidden="true" role="listbox" aria-labelledby="content_0_ucCourse_drpInstitution-button" id="content_0_ucCourse_drpInstitution-menu" style="width: 460px; height: 189px;" aria-disabled="false" tabindex="0" aria-activedescendant="ui-selectmenu-item-562">
<li role="presentation" class="">- Select -</li>
<li role="presentation" class="ui-selectmenu-item-selected">Australian Catholic University</li>
<li role="presentation" class="">Avondale College of Higher Education</li>
<li role="presentation">University of Wollongong</li>
<li role="presentation">Victoria University</li>
<li role="presentation" class="ui-corner-bottom">- Other -</li>
</ul>
</div>
None of this appears in the Page Source, so it is all generated on the fly. I am currently working around the Select issue by clicking the hyperlink object id=content_0_ucCourse_drpInstitution-button and then clicking the hyperlink object text=Australian Catholic University
Any better workarounds would be appreciated.

As you've already discovered, the dropdown is not represented by select->option in this case.
Handle it as is - find the a element by Id (which would be your "select"), click it to open up the dropdown; then, find the a element with text "Australian Catholic University" (which would be your "option") by link text:
IWebElement select = driver.FindElement(By.Id("content_0_ucCourse_drpInstitution-button"));
select.Click();
IWebElement option = select.FindElement(By.LinkText("Australian Catholic University"));
option.Click();
We can also think about the problem differently - if they've hidden the select element from us - we'll just make it visible. Cannot guarantee it would work since I cannot reproduce the problem:
((IJavaScriptExecutor)Driver).ExecuteScript("arguments[0].hidden = false; arguments[0].style.visibility='visible';", element);
where element is pointing to your select tag.
Then, after making the element visible try using SelectByText():
element.SelectByText("Australian Catholic University");

Related

How to select a value from Devextreme dropdown with Selenium C#

I need to select values (any value from House_TypeList) from dropdown menu with NUnit or just pure selenium. .
They are not seen in HTML.
I have tried select by xpath, by name, by span contains etc etc, I tried sending down key. I have waited for the element to become visible. I am out of ideas. Nothing works. I have not tried yet moving the cursor and trying to select it by that, but had a few problems implementing it and having in mind my luck, not really believing it will work either..
I am a beginner here, maybe I did some mistakes there. But I successfully managed any other inputs, buttons, navigation..
I have checked other similar questions, but could not find the answer that would work for me.
Is it even possible here?
Source:
<div class="dx-item dx-box-item" style="display: flex; min-height: auto; flex-grow: 1; flex-shrink: 1;"
<div class="dx-item-content dx-box-item-content" style="width: auto; height: auto; display: flex; flex-direction: column; flex-basis: 0px; flex-grow: 1;">
<div class="dx-first-col dx-last-col dx-field-item dx-field-item-required dx-col-0 dx-flex-layout dx-label-h-align">
<label class="dx-field-item-label dx-field-item-label-location-left" for="dx_dx-...._typeId">
<span class="dx-field-item-label-content" style="width: 159px;">
<span class="dx-field-item-label-text">Type:</span>
<span class="dx-field-item-required-mark"> *</span>
</span>
</label>
<div class="dx-field-item-content dx-field-item-content-location-right">
<div class="dx-textbox dx-texteditor dx-texteditor-empty dx-dropdowneditor-button-visible dx-widget dx-dropdowneditor-field-clickable dx-dropdowneditor dx-selectbox dx-validator dx-visibility-change-handler" id="slb_HouseManagement_EditHouse_TypeList">
<div class="dx-dropdowneditor-input-wrapper dx-selectbox-container">
<input type="hidden" value="" name="typeId">
<div class="dx-texteditor-container">
<input autocomplete="off" id="dx_dx-4e..._typeId" class="dx-texteditor-input" aria-haspopup="true" aria-autocomplete="list" type="text" readonly="" spellcheck="false" tabindex="0" aria-expanded="false" role="combobox" aria-required="true">
<div data-dx_placeholder="Select..." class="dx-placeholder"></div>
<div class="dx-texteditor-buttons-container">
<div class="dx-dropdowneditor-button dx-button-normal dx-widget" type="button">
<div class="dx-button-content">
<div class="dx-dropdowneditor-icon"></div>
</div></div></div></div></div></div></div></div></div></div>
Done. Found it in Devextreme support, the user had a bit different problem, but it solved mine as well.
IWebElement selectedItem = driver.FindElement(By.XPath("//div[#role='option']/div[text()='Apartment']"));
selectedItem.Click();
The DOM you have provided here does not contain any element for Lists. So I cannot share exact working code here. I will share few sample which you can update and use
With Selenium to select items from a list, you have two options to choose from:-
Select Class
Make an object of select class like below
Select obj =new Select(driver.findElement(By.id("search-box")));
Then you can use several functions on this select obj
obj.selectByVisibleText("Apartment");
Or
obj.selectByIndex(2);
or
obj.selectByValue("Farmhouse");
You can also get all the element in a List and then work around that list
List <WebElement> myHouseList = obj.getOptions();
System.out.println(myHouseList.size());
2.Actions Class
driver.manage().timeouts().implicitlyWait(10 , TimeUnit.SECONDS);
ele= driver.findElement(By.linkText("HouseList"));
Actions act = new Actions(driver);
act.moveToElement(ele).click();
WebElement webele = driver.findElement(By.linkText("Apartment"));
act.moveToElement(webele).click().build().perform();
Hope this helps you!!

Selenium/Chrome - Selecting a Checkbox Input without an ID

Thanks for the assistance in advance.
New to Selenium/Chrome and have had a good run of it until I hit a specific scenario.
I have a modal the contains 5 fields (3 drop-downs and a UL with 2 LI)
Each LI contains a label and input-checkbox.
All of the drop-downs have an Id so they were easy to manipulate with FindElement(By.Id("ID")).SelectText("TEXT");
However the Li's within the Ul do not have them and I have gotten NoSuchElementExceptions with every attempt to locate them.
<ul id="CertificatesToAdd" name="CertificatesToAdd" class="nav nav-list
checkbox-list add-certificate-required" data-trigger="manual" data- placement="top">
<li>
<label class="checkbox" style="font-weight:normal !important;">
<input type="checkbox" class="add-certificate-checkbox"
value="171">
Certificate of Registration
</label>
</li>
<li>
<label class="checkbox" style="font-weight:normal !important;">
<input type="checkbox" class="add-certificate-checkbox"
value="172">
Collection Agency License
</label>
</li>
</ul>
I have tried both of the FindElement lines below the todo and both return
OpenQA.Selenium.NoSuchElementException: Unable to locate element
new SelectElement(BaseTest.Driver.FindElement(By.Id("AddCertificateCountry")))
.SelectByText("Canada");
new SelectElement(BaseTest.Driver.FindElement(By.Id("AddCertificateState")))
.SelectByText("Alberta");
//TODO: correct input value for checkbox
new SelectElement(BaseTest.Driver.FindElement(By.CssSelector(
"#CertificateToAdd>li:nth-child(2)"))).SelectByValue("172");
new SelectElement(BaseTest.Driver.FindElement(By.XPath(
"//*[#id="CertificatesToAdd"]/li[2]/label/input"))).SelectByValue("172");
Any ideas would be helpful and appreciated.
To click on the checkbox associated with the <label> tags you can use the following solutions:
Certificate of Registration:
BaseTest.Driver.FindElement(By.XPath("//label[#class='checkbox'][normalize-space()='Certificate of Registration']/input[#class='add-certificate-checkbox']")).Click();
Collection Agency License:
BaseTest.Driver.FindElement(By.XPath("//label[#class='checkbox'][normalize-space()='Collection Agency License']/input[#class='add-certificate-checkbox']")).Click();
Here you're targeting the li:
new SelectElement(BaseTest.Driver.FindElement(By.CssSelector(
"#CertificateToAdd>li:nth-child(2)"))).SelectByValue("172");
Here your xpath means that input is a child of the label rather than a sibling:
new SelectElement(BaseTest.Driver.FindElement(By.XPath(
"//*[#id="CertificatesToAdd"]/li[2]/label/input"))).SelectByValue("172");
I think you can probably figure it out from there.

Selenium get element by XPath

I have following code where i want to select value for dropdown:
<div class="prod-value col-xs-6 col-sm-8">
<select class="selectpicker show-menu-arrow" data-style="btn-default btn-sm" data-width="98%" data-size="6" onchange="location=options[selectedIndex].value;" style="display: none;"><option value="/design-your-engagement-ring/choose-a-setting/10k-rose-gold-round-halo-engagement-ring/50277-E-10KR">10K Rose Gold</option>
<option value="aa">10K White Gold</option>
<option value="bb">10K Yellow Gold</option>
</select>
<div class="btn-group bootstrap-select show-menu-arrow" style="width: 98%;">
<button type="button" class="btn dropdown-toggle selectpicker btn-default btn-sm" data-toggle="dropdown" title="14K White Gold">
<span class="filter-option pull-left">14K White Gold</span> <span class="caret"></span></button>
<div class="dropdown-menu open">
<ul class="dropdown-menu inner selectpicker" role="menu">
<li data-original-index="0">
<a tabindex="0" class="" data-normalized-text="10K Rose Gold"><span class="text">10K Rose Gold</span><span class="glyphicon glyphicon-ok icon-ok check-mark"></span></a>
</li>
<li data-original-index="1">
<a tabindex="0" class="" data-normalized-text="10K White Gold"><span class="text">10K White Gold</span><span class="glyphicon glyphicon-ok icon-ok check-mark"></span></a>
</li>
</ul>
</div>
</div>
<input type="hidden" id="metal_type" name="metal_type" value="14KW">
</div>
How to do with selenium using c#. I have tried using xpath but it throws the error.
driver.FindElement(By.XPath("//*[#class='prod-value']/div/div/ul/li[0]/a")).Click();
Above code not able to find the exact path.
Try this:
//*[contains(#class,'prod-value')]/div/div/ul/li[1]/a
There were two issues with that xpath.
prod-value is not the only class present in first div
Element indexes are 1-based, so there's no li[0]
#derloopkat provided with correct explanation (+1)
Another simple way to solve the issue is to use link text (in case there are no more "10K Rose Gold" links):
driver.FindElement(By.LinkText("10K Rose Gold")).Click();
You need to click on the dropdown to expand its option before you can choose any option.
// expand dropdown options
driver
.FindElement(By.Css("div.prod-value button.dropdown-toggle.selectpicker"))
.click();
// choose option
driver.FindElement(By.LinkText("10K Rose Gold")).Click();
Firstly you need to expand the dropdown as Answered by Yong
Then you need to click element by using xpath as Answered by derloopkat
Here is final code for get final output:
driver.FindElement(By.CssSelector("div.prod-value button.dropdown-toggle.selectpicker")).Click();
driver.FindElement(By.XPath("//*[contains(#class,'prod-value')]/div/div/ul/li[1]/a")).Click();

Using Selenium (C#) Select an item from a drop down by text

I have been trying to figure this out and could use some help from Selenium experts here. I have a dropdown on my page that I am trying to select an option for from the test and I cant seem to get this right.
I have tried the following example I see commonly for select Item. The options always show text as an empty string "" even though I can see in the HTML markup the option text is there.
wait.Until(d => ExpectedConditions.ElementExists(By.Id("Cars")));
var carStatusDropDown = new SelectElement(_driver.FindElement(By.Id("Cars")));
carStatusDropDown.SelectByText(filter.CarStatus);
I figured its because maybe the options are not visible to the browser, so then I tried to click on the button next to dropdown (Bootstrap) so it would be open before it selects the text
wait.Until(ElementIsClickable(By.XPath("/html/body/div[2]/div[2]/div/div[2]/div[1]/div/form/fieldset/div[3]/div/div[1]/span[2]/div/div/span")));
IWebElement ddlButton = _driver.FindElement(By.XPath("/html/body/div[2]/div[2]/div/div[2]/div[1]/div/form/fieldset/div[3]/div/div[1]/span[2]/div/div/span"));
ddlButton.Click();
wait.Until(d => ExpectedConditions.ElementExists(By.Id("Cars")));
var carStatusDropDown = new SelectElement(_driver.FindElement(By.Id("Cars")));
carStatusDropDown.SelectByText(filter.CarStatus);
I can see the ddlButton opens the dropdown but am still getting >OpenQA.Selenium.ElementNotVisibleException
when it tries to SelectByText. In VS I can see the the options text still shows "" and the Displayed property is false for them. How can I find the options, Any feedback would be appreciated, I am posting the HTML below whats weird is that there are two drop downs one as a <ul> and a <select> one the appears below, I am trying to access the <select> one in the test code. The select one in firebug shows up as faded in the markup?!?
HTML:
<div class="combobox-container">
<input type="hidden" name="Estimate.EstimateStatus" value=" ">
<input type="text" autocomplete="off"
placeholder="All"class="combobox">
<ul class="typeahead typeahead-long dropdown-menu" style="top:
112px;left: 445.117px; display: none;">
<li data-value="Approved" class=""><a href="#"><strong>
</strong>A<strong></strong>p<strong></strong>p<strong>
</strong>r<strong></strong>o<strong></strong>v<strong>
</strong>e<strong></strong>d<strong></strong></a>
</li>
<li data-value="Hold" class=""><a href="#"><strong>
</strong>H<strong>
</strong>o<strong></strong>l<strong></strong>d<strong></strong>
</a>
</li>
<li data-value="In Progress"><a href="#"><strong></strong>I<strong>
</strong>n<strong></strong> <strong></strong>P<strong>
</strong>r<strong></strong>o<strong></strong>g<strong>
</strong>r<strong></strong>e<strong></strong>s<strong>
</strong>s<strong></strong></a>
</li>
<li data-value="Not Reviewed" class="active">
<a href="#"><strong></strong>N<strong>
</strong>o<strong></strong>t<strong></strong> <strong>
</strong>R<strong></strong>e<strong></strong>v<strong>
</strong>i<strong></strong>e<strong></strong>w<strong>
</strong>e<strong></strong>d<strong></strong></a>
</li>
<li data-value="Rejected"><a href="#"><strong></strong>R<strong>
</strong>e<strong></strong>j<strong></strong>e<strong>
</strong>c<strong></strong>t<strong></strong>e<strong>
</strong>d<strong></strong></a>
</li>
</ul>
<span class="add-on btn dropdown-toggle" data-dropdown="dropdown">
<span class="caret"></span>
<span class="combobox-clear">
</span>
</div>
<select id="Cars" class="combobox"
onchange="javascript:OnCarsStatusChanged();" style="display: none;">
<option value=" " selected="selected">All</option>
<option value="3ad8cf29-f0b7-441f-
81bc-c5cfe7c0d73d">Approved</option>
<option value="19b573c8-fc88-4abe-9c19-9ffc580a1ffe">Hold</option>
<option value="e3a8b2bd-c3eb-47c3-95e7-f15da2f3d25b">In
Progress
</option>
<option value="962e4bce-1ca5-404f-b7a0-6a3a42ad91a0">Not
Reviewed
</option>
<option value="c110e83a-5a93-4553-
a907-02a47ca97467">Rejected</option>
</select>
It does seems like there is another action depended on this dropdwon. By default this dropdown is NOT visible. So, best will be to see what previous action makes it visible.
However, another workaround can be to execute a simple javascript, make the dropdown list visible and select the intended element you need.
removeAttribute should remove the style attribute to make the list visible.
((IJavaScriptExecutor)Driver).ExecuteScript("document.getElementById('Cars').removeAttribute('style');");
By id = By.Id('Cars');
var carStatusDropDown = new SelectElement(_driver.FindElement(id));
carStatusDropDown.SelectByText(filter.CarStatus);

Edit webpage values and submit by button click?

HTML
<head></head>
<body class=" products show us">
<header id="header"></header>
<div id="wrap">
::before
<div id="container" style="opacity: 1;">
<div class="sidebar"></div>
<article itemtype="http://schema.org/Product" itemscope="itemscope">
::before
<figure>
<img id="img-main" src="test.jpg" itemprop="image" alt="test"></img>
<div id="zoom-lens"></div>
<div id="zoom-holder" style="background: url("test.jpg") no-repeat scroll 0px 0px transparent;" data-background-image="test.jpg"></div>
</figure>
::after
</article>
<div id="details" data-style-limited-with-count="0" data-style-limited="false">
<h1 itemprop="name"></h1>
<p class="style" itemprop="model">
White
</p>
<p class="description" itemprop="description"></p>
<ul class="styles "> // STEP 1: GENERATE LIST OF STYLES PER data-style-name and select the one that matches via adding "selected" to a class""!
::before
<li>
<a class="selected" data-style-name="White" data-style-id="10570" data-sold-out="false" data-images="{"detail_url":"..."..."}" href="..." data-no-tubolink="data-no-tubolink"></a>
</li>
<li>
<a class="" data-style-name="Black" data-style-id="10571" data-sold-out="true" data-images="{"detail_url":"..."..."}" href="..." data-no-tubolink="data-no-tubolink"></a>
</li>
::after
</ul>
<p class="price" itemtype="http://schema.org/Offer" itemscope="itemscope" itemprop="offers"></p>
<div id="cart-controls">
<div id="cart-controls"> // STEP 2 => OPEN THIS!
<form id="cart-addf" class="add" method="post" data-remote="true" action="/shop/168934/add" accept-charset="UTF-8">
<div style="margin:0;padding:0;display:inline"></div> // STEP 3: GENERATE LIST OF OPTIONS (UNKNOWN AMOUNT OF FIELDSETS) AND SELECT OPTION(S)!
<fieldset>
<select id="size" name="size">
<option value="25134"></option>
<option value="25135"></option>
<option value="25136"></option>
</select>
</fieldset>
<fieldset>
<select id="qty" name="qty">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
<option value="4"></option>
<option value="5"></option>
<option value="6"></option>
<option value="7"></option>
<option value="8"></option>
</select>
<a class="next" href="..."></a>
</fieldset>
<fieldset id="add-remove-buttons">
<input class="button" type="submit" value="add to cart" name="commit"></input> // STEP 4: CLICK BUTTON!
<a class="button continue" href="/shop"></a>
</fieldset>
</form>
</div>
</div>
<script id="cart-controls-add" type="text/x-nano-tmpl"></script>
<script id="cart-controls-remove" type="text/x-nano-tmpl"></script>
<script id="cart-controls-sold-out" type="text/x-nano-tmpl"></script>
<script id="cart-controls-limited" type="text/x-nano-tmpl"></script>
</div>
</div>
::after
</div>
<footer id="nav" style="opacity: 1;"></footer>
<script type="text/javascript"></script>
<script type="text/javascript"></script>
<script type="text/javascript"></script>
</body>
</html>
DESC
Above is the HTML code that I would like to access, modify values, & then submit data.
I am using c# net 4.0 and HTMLAGILITYPACK to achieve this.
I wrote inside the HTML above 4 total comments (4 things in total that is needed).
I was wondering if the goal of editing values is possible with HTMLAGILITYPACK and if it was possible to click a button on the webpage to submit the values that would be edited.
I found a few references regarding this matter but do not know how to put to proper use.
1: How to click a link element programmatially with HTMLElement?
2: Clicking button automatically using HtmlAgilityPack
PSEUDO CODE
HtmlAgilityPack.HtmlDocument doc = null;
doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(new WebClient().DownloadString("website above that contains that HTML"));
Not quite sure what you want to accomplish, but I think this might be on the right track:
See this to change any attributes in JQuery http://api.jquery.com/attr/
See this to change/add things that'll happen when you click something https://api.jquery.com/click/
Needless to say, I don't think you need to make the button "click itself", what's the point of it then? :P
But you can make it that if you click it, it does the first thing it should first, and then the second thing after that, within the JQuery click function you'll presumably make.
But like pasty said, I'd like you to elaborate a bit more, feel free to comment and ask if something is unclear in this post.

Categories