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.
Related
Can I use #Findby and pass certain values as parameter?
#FindBy("//div[contains(#class,'gallery_grid_image_caption gallery_grid_image_caption_padding')]"[$INDEX])
I know I can do this while using findElement. Kindly let me know if there is a solution/work around.
What I want to do it is let's say there is a for loop and there is a list of elements in a page. Now let's say the only thing that is changing among these fields is the bit of the xpath. //div/1, //div/2 .... What I want to do is represent one element for all these elements and pass the ending values as parameter.
I believe what you are trying to do is something like this :
#FindBy(xpath = "//div[contains(#class,'gallery_grid_image_caption gallery_grid_image_caption_padding')]")
public WebElement yourElement;
SO-9028757 should provide you more context.
I need to access the value of an element in a list in a different class. Here is how it goes:
In class DocumentManager.java:
Domain.Form form = new Domain.Form();
Services.Form wsForm = new Services.Form();
What I have not been able to do is to assign the value of versionLabel in the similar manner. I think this is because "version" is a List in "form" and String in "wsForm". I would want something like the following:
wsForm.setVersionLabel(form.getVersions().getLabel());
"label" has a String value. I want to assign that to versionLabel in "wsForm".
Thank you in advance.
You are working with a List and therefore you have to call
wsForm.setVersionLabel(form.getVersions().get(/index here/).getLabel());
What you were doing is calling a non-existing method for Lists on a List. In this way you can get to a certain Version in the list, and on this Version object you can call your getLabel method.
However, the real question here is, what index do you need? Or, put otherwise, are there multiple objects in the versions list? Because if not, you are overcomplicating things for yourself here.
Because form.getVersions() will returns List<Version> so you can't call below code:
wsForm.setVersionLabel(form.getVersions().getLabel());
If you want you can use following:
wsForm.setVersionLabel(form.getVersions().get(yourIndex).getLabel());// change index for object which you want
Note: You have to make sure which Version object's label you want to set in wsForm, In the example its just setting for first object. And make sure form.getVersions() is not null nor empty.
For last element
form.getVersions().get(form.getVersions().size()-1);
Based on your comments, that your versions increase every time someone modifies your form and if you want to get the version label of the most recent edit, you can do something like this.
int recentIndex = form.getVersions().size()-1;
wsForm.setVersionLabel(form.getVersions().get(recentIndex).getLabel());
As you're adding versions to list, the most recent version is the last version in your list, so get the label from that version
I need to get all elements with a class inside a wrapper div. I have done this before with php and the css selector would look something like this:
$this->elements($this->using('css selector')->value('div.active tr[class="theRow"]'));
Now this would give me all foo elements inside the wrapper active but I dont know how to do it with Java. I want a list with all the webElements like so:
List<WebElement> list = driver.findElements(By.cssSelector(".active,.theRow"));
This however will give me all theRow elements, eaven those outside the active wrapper. any sugestions?
the code below also give all theRow elements as expected:
List<WebElement> list = driver.findElements(By.className("theRow"));
but this gives me a empty list
List<WebElement> list = driver.findElements(By.cssSelector("tr[class='row-hover']"));
Is there a chance the class attribute of the span contains multiple values?
If so, then you may have problems using 'class=' as it would not match elements which have two or more classes.
If so, then try this;
List<WebElement> list = driver.findElements(By.cssSelector("div.active span.foo"));
When ever I access class outside of ".", I would always use "[class*='foo']" because you cannot guarantee the order in which multiple values appear in the class attribute, but would always use the "." notation where possible. However, whenever I use "class" in Xpath I always use "[contains(#class,'foo')] because Xpath always treats "class" as a string literal, where as CSS "." can cope with multiple values
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.
I'll write down the whole problem first.
A ring is a collection of items that has a reference to a current item. An operation -- let's call it advance--moves the reference to the next item in the collection. When the reference reaches the last item, the next advance operation will move the reference back to the first item. A ring also has operations to get the current item, add an item, and remove an item. The details of where an item is added and which one is removed are up to you.
Design an ADT(Abstract Data Type) to represent a ring of objects. Specify each operation by stating its purpose, by describing its parameters, and by writing a pseudocode version of its header. Then write a Java interface for a ring's methods. Include javadoc-style comments in your code.
So is it saying the Ring is like a class with operation that can move items by using a reference variable like T = items? And Advance would change T to represent a different item each time it's being called? Something like in UML format....
ADT: Ring
+advance(): T // move T to next item in collection and if T reaches last item, move T back to the first item.
+getCurrItem(): T // return item that T reference.
+addItem(item T): void // add an item in for T, No return.
+removeItem(Item: T): boolean // remove item that T reference and return true | false if it succeed or not.
Am I on the right track or am I supposed to do something else?
That looks like a good start to me. Now you have to work on designing the ADT and how you suppose you will store items and reference the end to the beginning. This is a data abstractions problem, and you can approach the implementation in several ways, but it's up to you to design it in an efficient way.