I have tried to use Html Elements framework. Here are one of my blocks:
#Block(#FindBy(id = "test"))
public class FirstBlock extends HtmlElement {
#FindBy(id = "nameS")
private TextInput id;
#FindBy(id = "saveBt")
private Button add;
public void addNewClient(String idText) {
add.click();
id.sendKeys(idText);
}
}
I have initialized page factory like:
PageFactory.initElements(new HtmlElementDecorator(driver), this);
Now I want to wait after add.click(); until next element is present.
As I found out where is possibility to use AjaxElementLocatorFactory
But how can I make this using Html Elements framework?
HtmlElements use AjaxElementLocatorFactory by default, so you don't need any explicit waits in your code. It will try to find your id element until succeed and then executes sendKeys() on it. In case element wait timeout will be reached, it'll throw ElementNotFound exception.
Related
I have a code which reads multiple string-arrays out of a dynamical dll. I'm creating GameObjects out of each string inside that array and i want to group each array of strings as unique groups.
So far, I've managed to give theese GameObject specific tags to group them, but theese tags were pre-created in the Unity Editor. This works so far, but in case the dynamic class provides more arrays than tags i have created previously, it won't be able to group the additional arrays.
My question: is there any way to create new tags via script while the game is running? With theese i could just simply add them to the new GameObjects.
In case that this shouldn't be possible, does someone have an idea of a different way to sort theese groups?
Thanks in advance!
In principle, the tag system is just a Dictionary of Lists. The problem is that Unity's Dictionary us defined at compile-time. The downside of rolling your own Tag system is you need some way to clear destroyed objects.
public class CustomTag : MonoBehaviour
{
private static Dictionary<string, List<GameObject>> Collection = new Dictionary<string, List<GameObject>>();
public static void Register(string tag, GameObject item) {
if (!Collection.ContainsKey(tag))
Collection.Add(tag, new List<GameObject>());
Collection[tag].Add(item);
}
public static void Deregister(string tag, GameObject item) {
if (!Collection.ContainsKey(tag))
return; // No Such Tag
// In case of multiple entries, remove all occurences of item
// If you're sure you will only have one entry per item, you can just use 'Remove'
Collection[tag].RemoveAll(m => m == item);
}
public static IEnumerable<GameObject> FindObjectsWithTag(string tag) {
if (!Collection.ContainsKey(tag))
return null;
return Collection[tag].AsEnumerable();
}
public string Tag;
private void Start() {
Register(Tag, gameObject);
}
private void OnDestroy() {
Deregister(Tag, gameObject);
}
}
Add this component to each GameObject you create, and set the Tag. It will take care of registering and deregistering. You can access the list of objects per tag using CustomTag.FindObjectsWithTag(). Note that with the current setup, objects won't register with the tag system until they Awake (which IIRC won't be until just before next update)
I need to get the WebElement name(Userdefine name) for reporting Purpose. Performing Click operation on AddMainConcernLink : If The element is Clicked/not .I need to report "AddMainConcernLink" is Clicked/not found
[FindsBy(How = How.CssSelector, Using = "[data-test-id='ECNMainConcernsLink']")]
private IWebElement AddMainConcernLink;
public void Click(IWebElement element)
{
element.Click();
Console.WriteLine("Perfomed click operation on element : " + element);
}
I want to Print Perfomed click operation on Element: AddMainConcernLink.
I simply pass a descriptive parameter along with the web element to my helper routines. For example, in a calculator Android app, I have the following:
public void clickDegreeRadsToggle() {
helper.click(degreeRadsToggle, "Degree/Rads Toggle");
}
And the helper.click method then logs using the passed description.
What is the best way to update a ContainerList in runtime. My addPullToRefresh in my ContainerList was just called, I go & fetch new data but how do I refresh the data to show in the ContainerList. How do I force it to rebuild itself with a new model?
I tried rebuilding a new ContainerList and replacing it in the Form, doing it all in a separate thread and doing it within a Display.getInstance().invoke... (tried all types of invoke), but I get a NullPointerException here
at
com.codename1.ui.plaf.DefaultLookAndFeel$1.animate(DefaultLookAndFeel.java:1599)
at com.codename1.ui.Form.loopAnimations(Form.java:1295)
at com.codename1.ui.Form.repaintAnimations(Form.java:1280)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1075)
at com.codename1.ui.Display.mainEDTLoop(Display.java:994)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
Learned more about the issue, so here is the actual question:
I have a container (WatchList) that has in it a ContainerList (LikeListView). When the ContainerList addPullToRefresh is called it makes a call to contentChanged() on its parent component (WatchList). The contentChanged creates a new LikeListView and replaces the old one with the new one. This is how the code looks like:
public void contentChanged()
{
final WatchList self = this;
Display.getInstance().scheduleBackgroundTask(new Runnable ()
{
public void run ()
{
CloudData.refreshLikeList();
Display.getInstance().callSerially(new Runnable()
{
public void run()
{
LikeListView lv = new LikeListView (self);
self.replace (myListView, lv, null);
myListView = lv;
}
});
}
});
}
It runs with no problem, but after it is done, there is a NullPointerException
com.codename1.ui.plaf.DefaultLookAndFeel$1.animate(DefaultLookAndFeel.java:1599)
at com.codename1.ui.Form.loopAnimations(Form.java:1295)
at com.codename1.ui.Form.repaintAnimations(Form.java:1280)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1075)
at com.codename1.ui.Display.mainEDTLoop(Display.java:994)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
It looks as if the old LikeListView is being called to animate by the look and feel, and it fails on line 1599 in DefaulrLookAdnFeel
cmp.getComponentForm().deregisterAnimated(this);
as cmp.getComponentForm() returns null for the removed component.
So, the old component is held somewhere in the DefaultLookAndFeel animated list? How do I get it out of there?
Thanks
-Yishai
Make the code that you used to create the initial list model and build ContainerList a method.
If you're using Netbeans, Highlight the block of code -> Right click -> Refactor -> Introduce -> Method and give it a name or press Alt + Shift + M.
Call that method inside the run() method of your addPullToRefresh.
Another thing you can do is call reloadForm();
For Example,
WebElement parentEle = driver.findElement(By.id("xyz"));
WebElement childEle = parentEle.findElement(By.id("abc"));
childEle.click();
In the above example, We are finding childEle with in parentEle.
How can we achieve this using #FindBy annotation (in conjunction with PageFactory)
First of all why do you need to find child from a parent if the child has a UNIQUE id? The main purpose of id is to provide the flexibility of finding the element with a unique selector.
In case if the child element is really nested to other, find that with xpath. I often use that.
#FindBy(how = How.XPATH, using = "//something/something")
private WebElement TestElement;
Or with ID
#FindBy(how = How.ID, using = "abc")
private WebElement TestElement;
This can be achieved in couple of steps:
//identify parent element with #FindBy annotation
1) #FindBy(className="locator")
List<WebElement> parent;
//loop through each parent to get child(<li> in your case) of each parent
2) for(WebElement list_items:Parent){
list_items.findElement(By.xpath("child locator"));
I had used this approach and was able to achieve the desired results. Hope this explains your query as well.
#FindBy (id = "abc")
private WebElement TestElement;
In your page factory try this and call that method from your test method.
public WebElement Child_Of_ParentElement(WebElement TestElement, String Child_Id)
{
return TestElement.findElement(By.id(Child Id));
}
As stated in other answers I would use xpath although you would have to rewrite the root path for each child element, unless you make a string constant or something but that could start to get messy.
// Child 1
#FindBy(xPath = "//[#id='xyz']/[#id='abc']";
private WebElement childAbcOfParentXyz;
// Child 2
#FindBy(xPath = "//[#id='xyz']/[#id='def']";
private WebElement childDefOfParentXyz;
I am working on selenium web driver using the language "Java" and want to access two elements of same classname. Actually, both the elements are error messages which are coming in small popup having the same class. But the problem is that every time it only picks the first element of the class which is coming. Please suggest which method I should use to get both the elements.
Also, I need to compare both the messages with the string that I have added. Here is the code I have tried:
public class mysignup {
public static WebDriver d;
public static void main(String []args)throws Exception{
d = new FirefoxDriver();
d.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
d.findElement(By.name("firstname")).sendKeys("qwertyuiokjhgfdsazxcvbnmkloiuytr");
d.findElement(By.name("firstname")).click();
d.findElement(By.name("lastname")).sendKeys("singh");
d.findElement(By.name("email_id")).sendKeys("abcgmail.com");
d.findElement(By.name("firstname")).click();
d.findElement(By.name("email_id")).click();
String bodyText = d.findElement(By.cssSelector(".popover-content")).getText();
While findElement returns you a single WebElement, findElements will return all elements that match given conditions.
In such a scenario I would suggest using findElements method. It will return you a list of all elements if found or an empty list. So you can try out with:
List<WebElement> lstEle = d.findElements(By.cssSelector(".popover-content"));
List<String> strLst = new ArrayList<String>();// list to contain all texts in each element
lst.forEach(new Consumer<WebElement>() { // foreach element add text to strLst
#Override
public void accept(WebElement t) {
strLst.add(t.getText());
}
});