I have searched the Selenium Webdriver APi docs hosted on google code. Currently using the PageFactory to initlize my Page objects, but having issue initilizing a list of WebElement.
What I need is a way to initialize a list of elements, ideally a list of drop-down select boxes.
I have looked at the API references to #Findsby and #ByChained but still can not figure out the best way to initlize a list of dropdown select boxes. I COULD have a seperate WebElement for each one and grab the ID but I would like to initlize a list of List selects
Currently I use the following:
public class PageObject {
#FindBy(id="element_id")
private WebElement element;
public getElement() {
return element;
}
}
Is there some way I can use something similar to the following that I seek:
public class PageObject {
#FindBys(className="selectItmes")
private List<WebElement> selects;
public List<WebElement> getSelects() {
return selects;
}
}
Or must I use a single Web Element for each element? :(
Update
Anyone know how to use the PageFactory and initlize a List elements; using the FindsBy annotation. I can't find any way of doing this yet there are google issues on the selenium google docs site saying this has been fixed in the Java api bindings and in version 2.12 as it was mistaken disabled in 2.11.... I still can't initialize a list. =/
This feature has been recently added in Selenium 2.0. Check this issue. It is fixed now.
From the documents, you could do something like,
#FindAllBy(className="selectItmes")
List<WebElement> selects;
If you are interested in the code, check this out
Here is standard solution what I do in our test framework, until #FindAllBy doesn't work in Selenium library:
private List<WebElement> selects;
public List<WebElement> getSelects() {
selects = getDriver().findElements(By.xpath("..."));
return selects;
}
You can find the select options fairly easily all you have to do is use the Webdriver.Support dll reference. This gives you access to the SelectElement class. Here's a quick example:
IWebElement element = driver.FindElement(By.TagName("select"));
SelectElement select = new SelectElement(element);
int options = element.FindElements(By.TagName("option")).Count();
select.SelectByIndex(new Random().Next(1, options - 1));
The above code finds the select element, get's a count of the options in that select element and then chooses one at random.
The code may be slightly different because my code is written in C#
#FindBys(#FindBy(xpath="//span[#class='ng-binding']"))
private List<WebElement> AllData;
public List<WebElement> getAllData() {
return AllData;
}
I solve this problem like So:
#FindBy(id="element_id")
public List<WebElement> selects;
You now have a list of all the web elements with that ID.
Then, you just grab the element out of the list like you would any other PageFactory WebElement list.
I know this is an oldie, but lost a lot of time with similiar issue. At my end problem was that I never really initialized the list. So this did not worked:
#FindBy(css = .randomlocator)
private List<WebElement> list;
but this worked:
#FindBy(css = .randomlocator)
private List<WebElement> list= new ArrayList<>();
Maybe it will help someone.
Related
I am using Flex Action Script.I am facing issue with static array. I have one static array used by two tabs.First time when I login the data is coming fine but if I am going to another tab and coming back to first tab then data from 2nd tab is appended into it and displayed in first.How to get rid of this problem?
//I'm assuming you have a var like this:
public static var sharedArray:Array;
//Then, assuming you're using a Spark TabBar, make sure you have a "change" listener defined for it, and make sure it includes the following code:
public function onTabChange(event:IndexChangeEvent):void {
sharedArray = [];
}
Can someone please help me figure out how to get Selenium Webdriver to find the frame after selecting Sign in??
https://www.guaranteedrate.com/agent/visitors
tap sign in
sendkeys to Username
#Test
public void fail() throws InterruptedException {
driver.findElement(By.linkText("Sign In")).click();
driver.switchTo().window("GB_window");
driver.switchTo().frame(0); driver.findElement(By.id("username")).sendKeys("testgr100#gmail.com");
}
Can you try this and tell me if it works? I suspect that what you are experiencing is a Firefox-only weirdness and a JavaScriptExecutor will get around it.
public void setEmailAddrOnFieldInSubFrame() {
driver.findElement( By.linkText("Sign In") ).click();
driver.switchTo().window("GB_window");
driver.switchTo().frame(0);
WebElement element = driver.findElement( By.id("username") );
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript( "arguments[0].value='testgr100#gmail.com';", element );
//cleanup frame position by switching back to previous window
driver.switchTo().defaultContent(); // always do this cleanup just in case
}
I think after clicking on Sign in you are taken to a frame, that is the registration form.
What you are trying is to Switch to a window first (GB_Window).
Try removing Switch to window call and just switch to frame and try your operations
After editing your code, use this
driver.findElement(By.linkText("Sign In")).click();
driver.switchTo().frame(0);
driver.findElement(By.id("username")).sendKeys("testgr100#gmail.com");
}
Try the below code. It worked for me. There are two frames before you can find Username Element. First frame is GB_frame and the second one doesn't have a any name given in the html source. So i have used index (frame(0)) for the second one.
#Test
public void fail() throws InterruptedException {
driver.findElement(By.linkText("Sign In")).click();
//switch to frames inside the webpage
driver.switchTo().frame("GB_frame"); //1st frame
driver.switchTo().frame(0); //2nd frame
driver.findElement(By.id("username")).sendKeys("testgr100#gmail.com");
}
Well if the application works on firefox then simply right click. In the context menu you will first find out if the element is under a frame or not by seeing an option This frame. Once you confirm this then inspect the element. Scroll top slowly in the firebug and you will find the iframe tag under which the element is present. In this manner you will get to know the name. If you want to know the count of all the iframes and their names then use
driver.findElements(By.tag("iframe")). This will return the list of webelements which have the tag and then you can iterate one by one and use getAttribute("name"). Note this will return the name only if the iframe actually has a name other wise will return empty.
I am new to vaadin and have a databinding problem. I have posted allready in the vaadin forum, but no answer up to now.
if you answer here, I will of course reward it anyway.
https://vaadin.com/forum/-/message_boards/view_message/1057226
thanks in advance.
greets,
Andreas
Additional information: I tried allready to iterate over the items in the container, after pressing a save button. After deleting all original elements in the model collection, and adding copies from the container, the GUI breaks. Some other GUI elements do not respond anymore.
I have personally never used ListSelect, but I found this from the API docs:
This is a simple list select without, for instance, support for new items, lazyloading, and other advanced features.
I'd recommend BeanItemContainer. You can use it like this:
// Create a list of Strings
List<String> strings = new ArrayList<String>();
strings.add("Hello");
// Create a BeanItemContainer and include strings list
final BeanItemContainer<String> container = new BeanItemContainer<String>(strings);
container.addBean("World");
// Create a ListSelect and make BeanItemContainer its data container
ListSelect select = new ListSelect("", container);
// Create a button that adds "!" to the list
Button button = new Button("Add to list", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
container.addBean("!");
}
}
// Add the components to a layout
myLayout.addComponent(button);
myLayout.addComponent(select);
The downside (or benefit, it depends :) of this is that you can't add duplicate entries to a BeanItemContainer. In the example above the exclamation mark gets only added once.
You can get a Collection of Strings by calling:
Collection<String> strings = container.getItemIds();
If you need to support duplicate entries, take a look at IndexedContainer. With IndexedContainer you can add a String property by calling myIndexedContainer.addContainerProperty("caption", String.class, ""); and give each Item a unique itemId (or let the container generate the id's automatically).
Im not sure I understand your problem but I belive that it might be that you haven't told the controller to repaint. You do this be setting the datasource like this after the save event has occured.
listSelect.setContainerDataSource(listSelect.getContainerDataSource());
I'm trying to follow the examples provided in this post, to create a dynamic list constraint in Alfresco 3.3.
So, I've created my own class extending ListOfValuesConstraint:
public class MyConstraint extends ListOfValuesConstraint {
private static ServiceRegistry registry;
#Override
public void initialize() {
loadData();
}
#Override
public List getAllowedValues() {
//loadData();
return super.getAllowedValues();
}
#Override
public void setAllowedValues(List allowedValues) {
}
protected void loadData() {
List<String> values = new LinkedList<String>();
String query = "+TYPE:\"cm:category\" +#cm\\:description:\"" + tipo + "\"";
StoreRef storeRef = new StoreRef("workspace://SpacesStore");
ResultSet resultSet = registry.getSearchService().query(storeRef, SearchService.LANGUAGE_LUCENE, query);
// ... values.add(data obtained using searchService and nodeService) ...
if (values.isEmpty()) {
values.add("-");
}
super.setAllowedValues(values);
}
}
ServiceRegistry reference is injected by Spring, and it's working fine. If I only call loadData() from initialize(), it executes the Lucene query, gets the data, and the dropdown displays it correctly. Only that it's not dynamic: data doesn't get refreshed unless I restart the Alfresco server.
getAllowedValues() is called each time the UI has to display a property having this constraint. The idea on the referred post is to call loadData() from getAllowedValues() too, so the values will be actually dynamic. But when I do this, I don't get any data. The Lucene query is the same, but returns 0 results, so my dropdown only displays -.
BTW, the query I'm doing is: +TYPE:"cm:category" +#cm\:description:"something here", and it's the same on each case. It works from initialize, but doesn't from getAllowedValues.
Any ideas on why is this happening, or how can I solve it?
Thanks
Edit: we upgraded to Alfresco 3.3.0g Community yesterday, but we're still having the same issues.
This dynamic-list-of-values-constraint is a bad idea and I tell you why:
The Alfresco repository should be in a valid state all the time. Your (dynamic) list of constraints will change (that's why you want it to be dynamic). Adding items would not be a problem, but editing and removing items are. If you would remove an item from your option-list, the nodes in the repository with this property value will be invalid.
You will not be able to fix this easily. The standard UI will fail on invalid-state-nodes. Simply editing this value and setting it to something valid will not work. You have been warned.
Because the default UI widget for a ListConstraint is a dropdown, not every dropdown should be a ListConstraint. ListConstraints are designed for something like a Status property: { Draft, Waiting Approval, Approved }. Not for a list of customer-names.
I have seen this same topic come up again and again over the last few years. What you actually want is let the user choose a value from a dynamic list of options (combo box). This is a UI problem, not a dictionary-model-issue. You should setup something like this with the web-config-context.xml (Alfresco web UI) or in Alfresco Share. The last one is more flexible and I would recommend taking that path.
I am trying to add some Sprite objects as the contents of an array, and I would like to be able to "clear" them from the stage. I would assume that if there are loaders involved, I need to do
_imgArray[i].close();
_imgArray[i].unload();
And if I am using a sprite, I can do:
removeChild(_imgArray[i]);
None of the above work. WHY???
For an example and/or description of how I am setting this up, see Joel's post here
...but note that he hasn't included a reference for deleting them from view.
Currently I try:
for(i = 0; i < _localXML.length(); i++)
{
var tmp:BMLink = new BMLink(_localXML[i], _bw, _bh, i);
_imgArray[i] = tmp;
_imgArray[i].x = (_bw + _mainpad) * i;
_base.addChild(_imgArray[i]);
}
But this doesn't work.
I would love it if someone could explain to me why this wouldn't be proper syntax.
The class instances that are populating the array are all extending sprite, but they have their own individual loaders inside w/ progress events etc.
jml
OK; I finally figured it out through a bunch of trial and error.
It seems that I was attempting to remove the child of my main class sprite (this) rather than the sub-sprite that I had added the children to.
Sorry for the noise, but for the record, if you find that you can't do
this.removeChild(_imgArray[i]);
it's not because you don't have the correct syntax, but because you might not have an
_imgArray[i]
at that particular point of your display list hierarchy... so...
_base.removeChild(_imgArray[i]);
...worked in this case.
jml
You can make an Interface IDestroy for example with a destroy method who will manage all cleaning/removing stuff :
public interface IDestroy{
function destroy():void;
}
public class MySprite extends Sprite implements IDestroy {
..
public function destroy():void{
// remove events
..
// remove loader
..
//remove from parent
if (parent!==null){
parent.removeChild(this);
}
// etc.. more cleaning
}
}
then when you have an object who is an instance of IDestroy you can call the destroy method
if (myObject is IDestroy){
IDestroy(myObject).destroy();
}
or another way
var id:IDestroy=myObject as IDestroy;
if (id!==null)
id.destroy();
Edit:
I don't understand why any of the method i gave you in the comment will not work but _base.removeChild(_imgArray[i]) will :
addChild and removeChild accept only a DisplayObject as a parameter, so if you can do _base.addChild(_imgArray[i]) it means that _imgArray[i] inherits from DisplayObject and _imgArray[i] has a parent.
So var myDisplayObject:DisplayObject=_imgArray[i] as DisplayObject; will not return null and you will be able todo myDisplayObject.parent.removeChild(myDisplayObject); which is a general approach to your problem without relying on your _base DisplayObjectContainer (MovieClip/Sprite/...)