I would like to select all childs and grandchilds and grand-grand etc. in root div,
But problem is: when collection of these selected elements has size greater than 55, The collection cut first half of elements,
I have 98 divs in my parent div overall, but selenium doesn`t know to sum them.
Try running this code and see how many elements are displayed, for me it showed 1000+ elements:
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
driver.get("http://yahoo.com");
List<WebElement> allElements = driver.findElements(By.xpath("//*"));
System.out.println("number of elements in the page: " + allElements.size());
driver.quit();
}
It doesn't really matter which elements are selected, you can change the xpath to By.xpath("//div") and it'll still show you 300+ results.
Could it be that your IDE only displays partial info during debug?
Related
I'm using RadListView and intercepting onItemLoading event.
Within that event, can I reference individual view elements inside the itemTemplate.
I see args.view._subViews - but I was wondering whether i could find element by name or something else. I assume id would not work because each item would have the same id.
You are correct getting by Id would only return the first one. However, if you have the reference to the ListView child group; using id will work to get the element out of a group.
Now if you use my NativeScript-Dom plugin then it is very simple; you can do:
var elements = RadListView.getElementsByClassName('someClass'); or RadListView.getElementsByTagName('Label'); or the newer functionality `
RadListView.runAgainstTagNames('Label', function(element) {
/* do something with this element */
});
And work with an array of elements that match your criteria.
Please also note that in a ListView that not all elements are preset; ListViews only have as many elements are needed to fill the ListView + 1 typically; so even if you have 2,000 items in the list view; you might only have 10 actual child ListView groups of elements. So when you did a GetElementsByTagNames('Label') you would only get 10 of them...
Following is my method where tableComponent is the table body element.
This method works fine when the text is visible in a row, but if the row has a scrolling and the text is out of view port, the method fails.
I tried the CSS as well, with out luck...
If I use the scroltoview option, I can get the text, but this is kind of a bootstrap, to scroll to the element, I need to find the right row and column, and to find the row and column, I only knows the text that it could appear in that cell.
This is Java, Selenium webdriver
public IUIElement getRowContainingText(final String text) {
return tableComponentElement.findUIElement(By
.xpath(".//tr[*[self::td|self::th]//text()[contains(.,\"" + text + "\")]]"));
}
Alternate solution-
List<webElement>rows=tableComponentElement.findElements(By.tagnamr("tr"));
for(webElement element:rows)
{
List<String>tabledata=rows.findElements(By.tagName("td"));
String desiredText=tableData.get(index);
//index will be the postion where text will appear in each row
}
I am trying to learn selenium by automating amazon.in
I would like to click on a moving image in an e-spot. It seems there is no class or id. Then how can i proceed?
WebDriver driver= new FirefoxDriver();
#Test
public void test() {
driver.get("http://amazon.in");
driver.manage().window().maximize();
WebElement menu = driver.findElement(By.xpath("//li[#id='nav_cat_2']"));
Actions builder = new Actions(driver);
builder.moveToElement(menu).build().perform();
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//a[#class='nav_a nav_item' and .=\"All Books\"]")));
WebElement menuOption = driver.findElement(By.xpath("//a[#class='nav_a nav_item' and .=\"All Books\"]"));
menuOption.click();
I have reached on the page. But dont know how to proceed after that.
URL
http://www.amazon.in/Books/b/ref=nav_shopall_books_all/280-9259056-7717210?_encoding=UTF8&node=976389031
As I can see, the images are getting scrolled, so just wait for the concerned image first and then click on it. I have added a code based on that:
wait = new WebDriverWait(driver,60);
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//div[#class='acsux-hero-wrap']//li[2]//img")));
WebElement ele = driver.findElement(By.xpath("//div[#class='acsux-hero-wrap']//li[2]//img"));
ele.click();
In the above code, the driver waits till the visibility of the 2nd image is located under 60 seconds. Then, it clicks on that element.
Similarly you can just replace the number li[2] with "li[1]" for first element, "li[4]" for fourth element, and so on.
Use other attributes such as width or alt
//img[contains(#alt,'Children')]
I was able to click on the highlighted image shown in your screenshot although its a different image with different keywords i reckon you'll need some bonded attribute for that image there to be able to click it regardless of its content or so and that'll be something like know the exact div the img tag this and so on.
hope this helps
I am using Selenium 2.0, Firefox 11.0, and Java to process a table. I have a table element composed of td cells, some which contain text included in a span element, others which contain input elements which have text in their value attributes. My goal is to get the text of every cell so I can output the table contents and compare them against expected values. I thought I would just do something like this:
Locate the table WebElement by id
List<WebElement> cells = tableElem.findElements(By.xpath(".//td"));
Then I would loop through all the cells and run findElements with the xpath ".//input" and if the list was empty I would run getText on the webElement, and if the list wasn't empty I would run getAttribute on the input element.
But to my surprise, this took several minutes to run on firefox (I'm afraid to try it on IE, which is where its supposed to be tested). When I debug it is obvious that the bottleneck is the .//input search from the td which is killing me. It is upwards of ten seconds, and so even with just a few cells my tests are taking forever. I've tried all sorts of minor variations to the xpath, tried going to css selectors, and continue to get the same results.
I want some advice about how to either tackle this problem differently or how to optimize my current method. I was hoping this would only take a couple of seconds.
I've included some sample code that should illustrate the slowdown I'm experiencing. This is not the website I'm screen scraping, but the slowness is the same:
webDriver.navigate().to("https://accounts.google.com/NewAccount");
List<WebElement> TDxpath = webDriver.findElements(By.xpath("//td"));
List<WebElement> TDcss = webDriver.findElements(By.cssSelector("td"));
for (WebElement td : TDcss) {
List<WebElement> q = td.findElements(By.cssSelector("input"));
}
for (WebElement td : TDxpath) {
List<WebElement> r = td.findElements(By.xpath(".//input"));
}
Do you really need a browser? You could try HtmlUnitDriver, that will be blazingly fast!
Or you could do it as a JS, that also only takes a fraction of time and you can get Lists from the script:
(JavascriptExecutor)driver.executeScript(
"var tds = document.getElementsByTagName('td');"
"for (var i = 0; i < tds.length; i++) {" +
" var inputs = tds[i].getElementsByTagName('input');" +
"}"
);
Scenario
In a screen I have 2 managers: 1) menu manager at the top and 2) body manager that has info/button elements. The menu manager does custom drawing so that its menu elements (LabelFields) are properly spaced.
Core Issue - Manager and subfield drawing order
The screen draws fine except when the user preforms an action (clicks a button) that results in an element withing the body manager being added/removed. Once field elements are added/removed from the body, the order in which the menu is drawn gets mixed up.
When the body manager adds or removes a field, instead of the menu manager drawing itself and then its sub elements (label fields), the menu manager begins to draw its sub elements and then itself; thus painting on top of the label fields and making them look like they've disappeared.
Comments
Already tried invalidate and other options -- I've tried to call invalidate, invalidateall, updateDisplay... after adding/removing field elements from body. All without success.
Removing custom sublayout works -- The only way that I can resolve this issue is to remove the menu managers custom sublayout logic. Unfortunately the menu system then draws in a traditional manner and does not provide enough spacing.
Below is the sublayout code for the menu manager, am I missing something here?
public void sublayout(int iWidth, int iHeight)
{
final int iNumFields = getFieldCount();
int maxHeight = 0;
final int segmentWidth = iWidth / iNumFields;
final int segmentWidthHalf = segmentWidth / 2;
for (int i = 0; i < iNumFields; i++)
{
final Item currentField = (Item)this.getField(i);
// 1. Use index to compute bounds of the field
final int xSegmentTrueCenter = segmentWidth * i + segmentWidthHalf;
// 2. center field inbetween bounds using field width (find fill width of text)
final int xFieldStart = xSegmentTrueCenter - currentField.getFont().getAdvance(currentField.getText())/2;
// set up position
setPositionChild(currentField, xFieldStart, getContentTop() + MenuAbstract.PADDING_VERTICAL);
// allow child to draw itself
layoutChild(currentField, iWidth, currentField.getHeight());
// compute max height of the field
//int fieldheight = currentField.getHeight();
maxHeight = currentField.getHeight() > maxHeight
? currentField.getHeight() + 2 * MenuAbstract.PADDING_VERTICAL
: maxHeight;
}
this.setExtent(iWidth, maxHeight);
}
Final Questions
Ultimately I want to keep the custom layout of the menu manager while being allowed to redraw field elements. Here are my final questions:
Have you experienced this before?
Why would the menu manager begin drawing in the wrong order when a field element is added/remove to the screen?
Does the native Manager.sublayout() do something that I'm not to maintain drawing order?
I haven't seen the behavior you describe, but the following line is a little troubling:
// allow child to draw itself
layoutChild(currentField, iWidth, currentField.getHeight());
getHeight() shouldn't return a sensible value until the field has had setExtent called through the layoutChild method. Though I'd expect that it would cause problems in all cases - not sure why this would work the first time around. In your logic I think you can safely just use iHeight instead of currentField.getHeight() in that line. The field will only make itself as big as it needs to be - it won't use all of iHeight unless it's something like a VerticalFieldManager