I'm trying to find list of element in ExtJS drop-down. I found a good solution on stackoverflow, though it doesn't work for me.
Solution in C#:
public void ClickComboItem(IWebElement input, string target)
{
input.Click();
IList<IWebElement> comboItems = _driver.FindElements(By.XPath("//*[contains(#class, 'x-combo-list') and contains(#style, 'visibility: hidden;')]//*[contains(#class, 'x-combo-list-item')]"));
comboItems.First(item => item.Text.Trim() == target).Click();
}
From here.
Part which I need to automate look like this:
<div class="x-ie-shadow" id="ext-gen546" style="z-index: 12004; filter: progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=4); WIDTH: 351px; display: none; height: 301px; top: 186px; left: 1187px;"/>
<div class="x-layer x-combo-list " id="ext-gen544" style="z-index: 12005; position: absolute; width: 350px; height: 302px; visibility: hidden; font-size: 12px; top: -10000px; left: 0px;">
<div class="x-combo-list-inner" id="ext-gen545" style="width: 348px; height: 300px; overflow: auto;">
<div class="x-combo-list-item" _nodup="30813" viewIndex="0">
<div class="x-combo-list-item" _nodup="30813" viewIndex="1">
Actual click on the pointer is executed and I can see see drop-down list on the page, though comboItem returns '0' results. I assume I should adjust xPath correctly for my case, though it seems for me that it should work, as soon as structure is very similar with an example from the post I mentioned above.
It seems that the xPath is not correct.
You gave "visibility: hidden;"
Try with ""visibility: visible;"
public void ClickComboItem(IWebElement input, string target)
{
input.Click();
IList<IWebElement> comboItems = _driver.FindElements(By.XPath("//*[contains(#class, 'x-combo-list') and contains(#style, 'visibility: visible;')]//*[contains(#class, 'x-combo-list-item')]"));
comboItems.First(item => item.Text.Trim() == target).Click();
}
You can take a different way without using Xpath
IWebElement dvInner = driver.FindElement(By.Id("ext-gen545"));
IList<IWebElement> comboItems = dvInner.FindElements(By.ClassName("x-combo-list-item"));
Try to implement using stable id of any of the parent nodes.Basically using the xpath-axis concept.
Related
I am devolping app using angular js and ionic framework. I want to show border right only for odd numbers.
Here is my code:
<div class="media-body" style="padding-bottom:25px;">
<h2 class="align_center">{{services.name}}</h2>
<a href="#job/{{services.id}}">
<h2 class="align_center_des">{{services.description}}</h2>
</div>
</div></div>
Here is the Css
.col-32-custom {
width: 32%;
float: left;
margin-left: 1%;
border-right: 1px solid #E4E4E4;
margin-bottom: 31px;
height: 144px;
}
Here is fiddle:
https://jsfiddle.net/asetkL0n/
CSS also allows you to target specific odd or even elements. An example to that could be:
.col-32-custom {
width: 32%;
float: left;
margin-left: 1%;
margin-bottom: 31px;
height: 144px;
}
.col-32-custom:nth-child(odd) {
border-right: 1px solid #E4E4E4;
}
wherein, inside that nth-child, you can pass, "odd","even","2n","2n+1", or any expression in n.
I think the best solution is to use ng-class, so you have to create a class that will only add the border right.
I presume you are in an ng-repeat loop so the code will look like
<div data-ng-class="{border-right: ($index%2)===0}" class="col-32-custom">
Here you have the condition for the even number ($index%2)===0 so the div will have border-right class on event number.
you can use ng-class-odd / ng-class-even within ng-repeat to add specific classes to this items.
example here : ng-class-odd
$scope.clickUpload = function(){
$timeout(function() {
angular.element('#upload').trigger('click');
}, 100);
};
For example, 3 times this works fine, but on 4th click - nothing going on
How can I fix this?
I am editing my original answer since I didn't fully understand what it is you are trying to do. You can style an input type="file" without having to use jQuery/javascript to hide the original element and simulate a click on it. You can use standard HTML/CSS to do this...
CSS:
.upload {
height:25px;
width:70px;
background:#ccc;
color:#fff;
overflow:hidden;
text:'Upload';
}
.upload input {
display: block !important;
width: 70px !important;
height: 25px !important;
opacity: 0 !important;
overflow: hidden !important;
}
#uploadText {
left: 6px;
position: relative;
top: -45px;
}
HTML:
<div class="upload">
<input type="file" name="upload" />
<h3 id="uploadText">Upload</h3>
</div>
Given these are not ideal styles and I have no future as a graphic designer, they are enough to demonstrate how you can modify the style of the standard input type="file" without needing javascript.
I am trying to a select option from extjs combo box.
Here in the below code listElements is giving only the visible options(which are shown in the screen) and not all the options.
Here am restricted to select one of the options which are available in the screen.
I want to select the value which are in the bottom of the list.
I don't find any option to drag down the list to select the desired option.
List<WebElement> listElements = TestUtil.getWebDriver().findElements((By.className("x-boundlist-item")));
for(WebElement ele : listElements){
if(ele.getText().equals(TestUtil.getValue(DateTimeConstants.TIMEZONE_INPUT_VALUE))){
ele.click();
break;
}
}
Please find the html :
This is the combo box html:
<input id="currentTimezone-inputEl" class="x-form-field x-form-text x-form-focus x-field-form-focus x-field-default-form-focus" type="text" style="width: 100%; -moz-user-select: text;" name="dateTimeData.selectedTimezone" value="-- Please Select --" autocomplete="off" aria-invalid="false" data-errorqtip="">
Options are available below like this:
<div id="ext-gen1024" class="x-reset">
<div id="ext-gen1074" class="x-reset">
<div id="ext-gen1076" class="x-css-shadow" role="presentation" style="z-index: 19000; left: -9999px; top: -9995px; width: 355px; height: 296px; box-shadow: 0px 0px 4px rgb(136, 136, 136); display: none;"></div>
<div id="ext-gen1079" class="x-css-shadow" role="presentation" style="z-index: 19000; left: 20px; top: 321px; width: 355px; height: 296px; box-shadow: 0px 0px 4px rgb(136, 136, 136); display: none;"></div>
<div id="boundlist-1022" class="x-boundlist x-boundlist-floating x-layer x-boundlist-default" tabindex="-1" style="left: 20px; top: 317px; width: 355px; z-index: 19001; height: 300px; display: none;">
<div id="boundlist-1022-listEl" class="x-boundlist-list-ct" style="overflow: auto; height: 299px;">
<ul>
<li class="x-boundlist-item" role="option">Africa/Abidjan</li>
<li class="x-boundlist-item" role="option">Africa/Accra</li>
<li class="x-boundlist-item" role="option">Africa/Addis_Ababa</li>
<li class="x-boundlist-item" role="option">Africa/Algiers</li>
<li class="x-boundlist-item" role="option">Africa/Asmara</li>
<li class="x-boundlist-item x-boundlist-selected" role="option">America/St_Lucia</li>
</div>
</div>
</div>
Yes, I can reproduce this issue. The reason is that Selenium won't click on invisible elements, each of the invisible element's text will also be empty.
Here most of the combo list elements are invisible, so ele.getText() won't get you anything for them. As a result, you won't be able to compare the text with the one you want.
However, the workaround is, without using ele.getText() to get the text, you can try use textContent attribute of an element to get the text. Also, Selenium won't click on invisible element, so you need to use Actions click() rather than normal click(). Below is how you can do it.
List<WebElement> listElements = TestUtil.getWebDriver().findElements((By.cssSelector(".x-boundlist:not([style*='display: none'])")));
for(WebElement ele : listElements){
if(ele.getAttribute("textContent").equals(TestUtil.getValue(DateTimeConstants.TIMEZONE_INPUT_VALUE))) {
// print out ele.getAttribute("textContent") if you want
// ele.click(); ElementNotVisible exception may be thrown
new Actions(TestUtil.getWebDriver()).click(ele).perform();
break;
}
}
}
To solve this we can use xpath in the following manner. The reason why a country is not selected is it is not visible and for invisible elements selenium cannot perform the action.
We have to first make the countries list visible by clicking on the input box. Once the list is visible we can select any of the country in the list.
// Code to make the country list visible
WebElement element = driver.findElement(By.xpath("//div[contains(#id, 'boundlist')]"));
element.click();
//To click on some country in the drop down
driver.findElement(By.xpath("//div[contains(#id, 'boundlist')]//ul//li[text() = 'Africa/Abidjan']")).click();
//To make a reusable method
public void selectCountry(String countryName)
{
driver.findElement(By.xpath("//div[contains(#id, 'boundlist')]//ul//li[text() = '" +countryName +"']"));
}
I am pretty new to Selenium Webdriver, so pardon me for all d 'noob' terminology used.
I have a dynamic table on the page, with 4 columns in the table. Out of this, only the first column name can be edited. The table looks like this :
Now using Webdriver, I need to locate 'group102' and verify the Level and the number of Cards (basically the text of the rest of the two columns) corresponding to 'group102'. The key point to note here is that this group is dynamic in nature. Right now, its sitting in row 3 but tomorrow, it may be on row 1 or row 10.
I am using Visual Studio (C#) and Selenium webdriver.
Please let me know how can I progress
EDIT :
HTML CODE:
<div id="formbland-1013" class="x-panel x-panel-default x-form-bland x-form-base" style="height: 9588px;">
<div id="formbland-1013-body" class="x-panel-body x-panel-body-default x-panel-body-default" style="left: 0px; top: 0px; width: 680px; height: 9588px;">
<span id="formbland-1013-outerCt" style="display: table; width: 100%; table-layout: fixed;">
<div id="formbland-1013-innerCt" style="display:table-cell;height:100%;vertical-align:top;">
<div id="ext-comp-1026" class="x-panel x-panel-default x-form-bland x-form-base" style="width: 680px; height: 47px;">
<div id="ext-comp-1036" class="x-panel x-panel-default x-form-bland x-form-base" style="width: 680px; height: 9541px;">
<div id="ext-comp-1036-body" class="x-panel-body x-panel-body-default x-panel-body-default" style="left: 0px; top: 0px; width: 680px; height: 9541px;">
<span id="ext-comp-1036-outerCt" style="display: table; width: 100%; table-layout: fixed;">
<div id="ext-comp-1036-innerCt" style="display:table-cell;height:100%;vertical-align:top;">
CODE WHICH I AM TRYING :
ReadOnlyCollection<IWebElement> select = WebDriver.FindElements(By.XPath("//td[contains(text(),'group102')]"));
if ("group102e".Equals(select.ToString()))
{
throw new SystemException("Group matches according to the Access");
}
else
{
throw new SystemException("Group does not matches according to the Access");
}
I can't provide exact code as I don't know the HTML for the table. But here are the code in theory.
You get the IWebElement input first by text first, then go to ancestor td's siblings (i.e. the next two column cells in this row), then get the element's text.
IWebElement inputGroup = WebDriver.FindElement(By.CssSelector("tbody input[value='group101']"));
IWebElement level = inputGroup.FindElement(By.XPath("(.//ancestor::td/following-sibling::td)[1]"));
string levelA = level.Text;
My questions about your code:
"group102e".Equals(select.ToString()) doesn't make sense, since your select is ReadOnlyCollection<IWebElement>, which is a list of IWebElements, ToString won't get you anything useful?
var location = WebDriver.FindElement(By.CssSelector("tbody input[value='Practice Wide Group 2']")).Location.ToString();, what do you want here? The location of the element (which is in the type of System.Drawing.Point)?
In my extjs project, I have some panel's to which I am showing toolbar on mouseEnter event. This is working fine. But when I just update the panel with new html then the mouseenter event is not working on it.
panel.update('hello');
Then I realised through Chrome developer tool that the update method is erasing the last nested div inside panel before writing the new text to it (ie 'hello').
Each panel has 3/4 nested div's but when we use update(), the panel has only 2 nested div's?
This was the main reason which was not invoking the mouseenter event on the panel because I think the Ext is unable to identify the panel as a valid panel after update() method.
Anyway, later I solved this issue by checking the panel variable in chrome console like below.
panel.body.dom.childNodes[0].children[0].childNodes[0].data = 'hello';
The above implementation looks disgusting but it worked for me. Any other nice way to do this?
Edit :
//In controller
this.control({
'#monthCalendar>panel>panel': {
render: function(container){
container.on('mouseenter',function(){
//do something here
},container,{element: 'el'});
}
}
})
Before Update:
<div class="x-panel x-box-item x-panel-default" id="panel-1078" style="left: 870px; top: 0px; margin: 0px; width: 174px; height: 52px;">
<div id="panel-1078-body" class="x-panel-body x-panel-body-default x-panel-body-default x-box-layout-ct" style="width: 174px; height: 52px; left: 0px; top: 0px;">
<div id="panel-1078-innerCt" class="x-box-inner " role="presentation" style="height: 50px; width: 172px;">
<div id="panel-1078-targetEl" style="position: absolute; width: 172px; left: 0px; top: 0px; height: 1px;">
March 01
</div>
</div>
</div>
</div>
After update:
<div class="x-panel x-box-item x-panel-default" id="panel-1078" style="left: 870px; top: 0px; margin: 0px; width: 174px; height: 52px;">
<div id="panel-1078-body" class="x-panel-body x-panel-body-default x-panel-body-default x-box-layout-ct" style="width: 174px; height: 52px; left: 0px; top: 0px;">
February 01
</div>
</div>
I am available on Sencha chat room.
Your event handler stops working because your update() erases the inner elements added by the panel's layout.
You are using either HBox or VBox layout on your panel, which adds additional HTML elements inside the main one, as you noticed. If you call update() on the main component's element, you erase the inner elements added by the layout, including that on which your event handler was listening.
The solution is to either:
use a simpler layout on your panel, such as Auto;
or
update the inner element added by the layout:
panel.getLayout().targetEl.update('Updated');
If you want to update the content of a panel, you should call
panel.body.update('hello');
This will update content area element only and will not ruin the panel integrity. As far as I know, calling update directly on panel is wrong, because call to function inherited from AbstractComponent will not take into account internal panel's structure and will overwrite essential panel's markup.