I wanna extract data from site
For example when i try to get Price with below code, i can't.
deal.getDetail().setPriceElement(content.select("div#main-new div.buy-now-aligner div.buy-now-price").first());
But i can extract data from deal.getDetail().setPriceElement(content.select("div#main-new").first());
I can't reach the sub divs, how could it be?
You are using the method first() in the wrong way.
Look at the Jsoup API;
public Element first()
Get the first matched element.
Returns:
The first matched element, or null if contents is empty.
This meaning, the Element object that is returned is the first matched of your selection, in your case the first buy-now-price div class.
If you want the child elements of that element, (there is only one in your example URL), you can use either the child() method or the children() method.
The first method takes a parameter that is the index of the child you want, and the second method returns a collection of Element objects as Elements.
Use either that is suitable for you.
Related
As far as my understanding goes, FindBys Annotation in pagefactory returns you elements which satisfies all the condition mentioned inside. The code below always returns 0 elements.
Similarly,If I'm using FindAll annotation with same id and Xpath attribute it is returning me 2 webelements. Can anyone help me in understanding the results.
#FindBys
(
{
#FindBy(xpath="//*[#id='ctl00_ctl00_divWelcome']"),
#FindBy(id="ctl00_ctl00_divWelcome")
}
)
public List<WebElement> allElementsInList;
Your understanding is wrong.
The documentation for #FindBy says:
Used to mark a field on a Page Object to indicate that lookup should use a series of #FindBy tags in a chain as described in org.openqa.selenium.support.pagefactory.ByChained
Further, the documentation for ByChained says:
Mechanism used to locate elements within a document using a series of other lookups. This class will find all DOM elements that matches each of the locators in sequence, e.g. driver.findElements(new ByChained(by1, by2)) will find all elements that match by2 and appear under an element that matches by1.
So in your example, you are looking for an element by XPath with a specific ID, and then its child element by the same ID ... which, of course, is not going to return anything.
I have a data structure that is of type List<List<CustomObject>>. I want to be able to find the position of a particular CustomObject in my data structure. The output would show me the index for e.g. 1,0 which means the CustomObject is the 0th element in the 1st list item.
I have thought of the following ways to implement this:
Loop through the list one by one and compare the CustomObject. Of course i'll have to implement the equals method in CustomObject to compare.
Use the indexOf method to figure out the first index of the data structure which has the CustomObject. However in this the parameter to equals would be List<CustomObject>.
Are there any other efficient ways to get the index?
Iterate over the main list and call .contains () to check if object is there. If true, use indexOf() to locate it.
You must properly implement equals() and hashcode() in your object .
You can also use .lastIndexOf(Object o) method to get the index of your object directly in one call. This method will give you -1 if that object does not exist in the list.
Check the doc for more detail.
http://docs.oracle.com/javase/7/docs/api/java/util/List.html#lastIndexOf(java.lang.Object)
The only issue is this method will give you only the last occurrence of the object. If you have duplicate objects in the list, this will not work.
Also you must properly implement equals and hashcode method for proper comparison to occur.
indexOf iterates for you, so 1) and 2) are actually the same. And if the element you're looking for is in the last slot of the last list you iterate over the entire dataset.
To get better then that, you'll have to store the index explicitly in a second datastructure that allows for more efficient searching. Taking the winner in the "search" category for datastructures from http://bigocheatsheet.com/ - a HashMap in java - you could do it as follows:
In a HashMap<CustomObject, Index> you store per object the desired index. That also needs to be updated each time you update the list. Both updating and searching for an item requires only constant time, in other words is independent of the amount of elements you have.
With such a map in place, instead of searching through your list, you'll do map.get(customObject) and you'll have the result.
The question for you to answer: can you keep such a datastructure up to date consistently and with less effort than searching in a list. Because if you update your list in a way that affects multiple elements you may loose all benefit due to constantly redoing the entire map.
Besides using multiple datastructures, maybe there is 1 that fits both needs better than a list and a map. But that depends on your data and how you need to access it and which part thereof needs to be optimized.
So I have a variable that uses a method. Something like this:
By locator = By.id("something-"+getDynamicId());
Usually the id changes numbers like this: something-1 to something-2 (not those exact numbers, always different). I have a way of getting the number it changes to by calling the getDynamicId() method. The problem is, when I start my test the id is set at the start and whenever I click on a specific button, the id changes but my variable does not. Is it possible for the locator variable to call getDynamicId() everytime locator is called? Maybe everytime I click on the specific button the locator reloads?
I have looked up ClassLoaders but I do not know how to use it nor do I know if it can even do what I want.
Instead of doing that, i've gotten around dynamic ID's by using CSS.
driver.findElement(By.cssSelector("element[id^='something']"));
This means "find an <element> tag, that has an id attribute that starts with "something"
If there are multiple elements that match this, then you need to increase your specificity. You can do this by selecting some parent.
div.some-div [id^='something']
^ the space here meaning "a descendent of.."
this page may help with formulating CSS selectors like this for Selenium.
Also, in addition to what #sircapsalot has done, you can use xpath for working with dynamic ids as below (As you said in comment, there are multiple element having ids that contains "something"):
List<WebElement> elements = driver.findElements(By.xpath("//tag[contains(#id,'something-')]"));
//Say you want to click on 4th element now then use the below code(assuming the list has more than or equal to 4 elements in it)
elements.get(3).click();
Here, it will locate all the elements with tag as "tag" and has "id" that contains the text "something-" and then click on the 4th element in the list.
But, if you want to retrieve the dynamic ID and use it for clicking on the specific element, you can create a new method like this :
public static void clickOnDynamicElementById(String partial_locator_id){
//Code for getting dynamic id and then storing the retrieved dynamic ID in a string, say "dynaID";
String locator_id_to_click = partial_locator_id + dynaID;
driver.findElement(By.id("locator_id_to_click")).click();
}
Then, you can call this method directly in your main method as below:
clickOnDynamicElement("something-"); //because main method is also static, it can call the method directly.
I need to create a temporary DOM-element which is independent from my main document. I do it by using my main document to create an element but not appending it to the tree.
Element temporaryParentElement = document.createElement(PERMISSIONSET);
It is used to build tables in a dialog. After the dialog is closed i don't need this element anymore so I tried to remove it:
document.removeChild(temporaryParentElement);
This resulted in an exception:
org.w3c.dom.DOMException: NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist.
If i understand it correctly the created node cannot be removed if it isn't a part of the tree. Do I need to append it to the tree and then call remove method? Or does the garbage collector take care about this element?
Element creation is different from appending or removing it to an existing tree. You use that document reference to create the element, but then append it to some other element. You can remove it using the reference of that element.
The method removeChild removes an element from a tree where it was added before (with appendChild or parsed when the document was read).
You have to find the element that represents the parent of that element in order to remove it. Suppose the parent is dialog. You would use:
dialog.removeChild(temporaryParentElement);
I guess this question that would have already been asked here. I searched but could not find anything similar. So here goes --
I have a custom data object Method and Method is as follows --
public Class Method {
List<String> inputParameters;
String resultVariableName;
}
Now i have a LinkedList<Method> which acts as a repository of Method objects.
Given a Method object is there a way in which the correct index of the Method object can be concretely determined.
My question arises from the face that LinkedList class has an indexOf routine but this routine returns the first occurrence of the object but then there is no given that 2 copies of Method object can not reside in the LinkedList(right ?)
Would tagging every Method object as I add it to the LinkedList solve my purpose and if so is there an ideal way to do it ?
EDIT :
Explaining my use case a little further.
My code basically reads a Velocity template top-down and creates Method objects. One Method object is created for every velocity routine encountered.
This explains why the same element can be stored at multiple indices in the LinkedList as there is no real restriction on how many number of time a Velocity routine is called or the inputs/results provided to the Velocity routine.
Now, i have a UI component, one JButton per Method object reference in the LinkedList<Method> by using which the user can click and edit the Method object.
Thus i need to know which exact Method object reference to edit in the event that same elements reside twice or more number of times in the LinkedList<Method>
What do you mean by the "correct" index in the first place? If the linked list can contain the same element twice or more (and be careful here - the list will only contain a reference to a Method object, not the object itself) then which index would be "correct" in your view?
Of course you can just iterate over the linked list yourself and return all indexes at which a given Method reference occurs, but it's not clear what you're trying to do with it.
Note that indexes aren't often used with linked lists to start with, as obtaining the element at a given index is an O(n) operation.
Duplicates are allowed in LinkedList's.
LinkedList does not avoid duplicates, it may have more than one copy.
You can put a logic to avoid multiple instances, extend the linkedlist class and override the add function to check if Method object already exists.
OR
If you want to get all instances of the Method object, you can use a ListIterator and collect all instances of it, and return this collection as a result.
"there is not given 2 copies of Method object can not reside in the LinkedList", if this is a scenario, how will you identify which object to retrieve??
In this case, I would suggest you to use a LinkedHashMap, where you can use a Identifier as a key to uniquely identify a Method's object.