How can I call a predefined Geb Page element using WebDriver? - selenium-webdriver

I created a re-usable WebDriver method, but I can't for the life of me figure out how I can call a predefined Geb page CSS selector using WebDriver.
This method works, but I can't seem to call it using WebElement element:
static void WaitVisibilityOfElement(WebDriver driver, By cssSelector, int timeoutInSeconds) {
WebDriverWait Wait = new WebDriverWait(driver, timeoutInSeconds)
Wait.until(ExpectedConditions.visibilityOfElementLocated(cssSelector)).click()
}
This is the element I am trying to call, and I want to just be able to use the name of the element flipperCardOne, but if I do that it doesn't work.
flipperCardOne(wait:true) {$ (".flex-item:nth-child(5) .front > .w-100")}

Geb's selector results (the things returned from calls to $()) are called Navigators and are a wrapper around collections of Selenium's WebElements. Because Navigators can be created from more than just css selectors (you can chain multiple find() calls on them, you can base them off xpath expressions and you can filter contents of them by matching their text, just to give a number of examples) you cannot map one to one from a Navigator to a css selector. If your intention is to always wait for flipperCardOne to be visible before interacting with it then the idiomatic way to do that would be to use waitCondition content option:
flipperCardOne(wait:true, waitCondition: { it.displayed }) {$ (".flex-item:nth-child(5) .front > .w-100")}
Then you could just do flipperCardOne.click() and it would work.
And if you insist on using a method similar to what you listed in the question (and I'd argue that it's not the right thing to do) then you'd need something like:
static void WaitVisibilityOfElement(WebDriver driver, WebElement webElement, int timeoutInSeconds) {
WebDriverWait Wait = new WebDriverWait(driver, timeoutInSeconds)
Wait.until(ExpectedConditions.visibilityOf(webElement)).click()
}
and then call it like:
WaitVisibilityOfElement(browser.driver, flipperCardOne.singleElement, 5)

Related

How to Handle this type of Popups is selenium WebDriver Using Java

How to Handle this type of popups using selenium with java, tried Using getWindowHandles method but cant figure Out the Problem
It is only possible to give a generic answer to your question on how to get rid of an ad popup.
Please be aware, that you must make sure to really alway get the same ad popup and this is usually not the case with advertising.
Assuming that you always get the exact same (also the implementation) popup, you must first inspect the popup or directly the close button within the popup and find some attributes that can be used to identify the close button element.
Let‘s now also assume that the close button can be identified, you are pretty much done and only need to use selenium to select the element (the css selector is just an example) and send a click command.
element = driver.findElement(By.cssSelector("input[value='close']"));
element.click();
Pop up can be handled with window handlers
String mainwindow=driver.getWindowHandle();
// To handle all new opened window.
Set<String> s1=driver.getWindowHandles();
Iterator<String> i1=s1.iterator();
while(i1.hasNext())
{
String ChildWindow=i1.next();
if(!MainWindow.equalsIgnoreCase(ChildWindow))
{
// Switching to Child window
driver.switchTo().window(ChildWindow);
element = driver.findElement(By.cssSelector("input[value='close']"));
element.click()
// Closing the Child Window.
driver.close();
or else we can use alert
Alert confirmationAlert = driver.switchTo().alert();
String alertText = confirmationAlert.getText();
System.out.println("Alert text is " + alertText);
confirmationAlert.accept();

Application of DOM locators in Selenium

I understood DOM locators but I don't know how to apply and locate the elements using DOM locators. I automate using Selenium with java but in DOM we have to locate writing document.getElementById("id of the element"). Copying same thing in Java code gives me error. Does any Library needs to be imported to use DOM locators or something else ?
If you want to use document.getElementById function inside your Java Selenium tests you can go for JavaScriptExecutor.executeScript() method like:
WebElement element = (WebElement) driver.executeScript("return document.getElementById('id of the element');");
however much easier would be using WebDriver.findElement(By.Id)
WebElement element = driver.findElement(By.id("id of the element"));
it is less code, more clear, faster and you will be able to use Explicit Waits in case of testing AJAX applications
WebElement element = new WebDriverWait(driver,10)
.until(ExpectedConditions
.presenceOfElementLocated(By.id("id of the element")));

How to wait for page load to complete in Chrome browser

What is the command in webdriver to wait for page to load fully before performing action on the page in CHROME browser?
PageLoadTimeOut is not waiting for the page load to complete in Chrome whereas it is working fine in firefox.
In Chrome, if webelement is there on the page, webdriver is performing the action on webelement while page is getting loaded. This is causing scripts to fail randomly with exception 'element is not clickable'.
Please let me know if there is any solution for this.
Thanks
You can use custom wait methods for an element to be enable or visible on the page.
For Example create a custom method isElementEnable using following code:
driver.findElement(locator).isEnabled();
Or use the following code to check if the element is visible on page:
driver.findElement(locator).isDisplayed();
pass your element locator as input parameter to the method.
Or Alternatively use implicit wait:
driver.manage().timeouts().implicitlyWait(number_of_seconds, TimeUnit.SECONDS);
Hope this will help.
You can use the JavaScriptExecuter.executeScript to get document.readyState,to compare it to complete,as a condition to WebDriverWait.Like this:
WebDriverWait wait = new ...;
wait.until(new ExpectedCondition<Boolean>(){
public Boolean apply(WebDriver driver) {
return (JavaScriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
});
Unfortunately, with Chrome if you have a alert on page,you will get a UnhandledAlertException.And this will not occur for Firefox
It's a really old question, but anyone having the same question might find this useful:
For chromedriver, it is best to use sleep method:
import time
# some of your code
time.sleep(2)
# here your program will wait for two seconds
# rest of your code
You can find an appropriate time span that will ensure your page loads and pass that time as parameter. But using too big time will make program slower.

How to handle Element is no longer attached to the DOM in page object?

I'm trying to test the web site using Page Object, When I'm executing my scripts, I'm getting Element is no longer attached to the DOM (Selenium::WebDriver::Error::StaleElementReferenceError) error message intermittently while calling a function.
How can I overcome from this issue, If any suggestions?
We also faced the same problem in our project. One way of overcoming this is to use a try catch block within the method which is causing this problem. Inside the catch block again re execute the same lines of code/another method. This will take care of the issue.
You get this exception when the element you are interacting with has been changed in the DOM. If you capturing the element in the WebElement object and then using that object further to perform some clicks/typing and if in between the reference to that element changed, then the object you are using will no longer refer to a correct locator. Try using the element locators at the time of interacting with the element instead of capturing it in a WebElement object first and then using that object further.
E.g. instead of doing :
WebElement e = driver.findElement(By.id("someID"));
e.click();
.
.
.
e.click();
try to use :
driver.findElement(by.id("someID")).click();
.
.
.
driver.findElement(by.id("someID")).click();
Otherwise, you can use Vinay's method.
Use PageFactory to initialize your page objects.
It will create lazy proxies to the actual element.
public class PageObject {
#FindBy(id="someID")
private WebElement someElement;
public void doSomething() {
someElement.click();
}
}
PageObject po = PageFactory.initElements(driver, PageObject.class);
If you do not use #CacheLookup along with #FindBy, any time you use someElement, it will go and look for this element using the finder.

GWT, access RichTextArea by non-GWT (or "regular") javascript

I am writing a pretty simple CMS on GAE, and I want my users to be able to upload images.
I have written the part that does the actual uploading and showing the images, and here's what I'd like to do:
Show the usual form for new posts (with a widget that contains a rich text area and a format bar for it) and the list of images the user has ever uploaded (done). Then i want an image to appear in the text area when the user clicks that image.
I generate the list of images on the server, and i can't find a way to call any methods on the Rich Text Area from non-GWT javascript. And I don't really want to generate the list of images by means of AJAX, because it seems quite cumbersome and, hopefully, with the advent of HTML5 it is going to be much simpler.
Well, the question is, how can i access a RichTextArea in a widget from a normal javascript on a page, or is there another way of inserting an image into it (i.e. another is there a way to generate a list of images so that they would be in a kind of widget, but without the use of AJAX).
Thank you.
To answer your general question of getting access to your GWT code from hand written Javascript, you can use the general built in method or Ray Cromwell's gwt-exporter project. This way, you can expose the specific methods of the RichTextArea instance you're trying to access from external Javascript.
As for your other question, generating a list of Images should only require getting the urls for the images and creating a bunch of Image objects with the given URLs. Then display this list in a PopupPanel or some other widget.
Here is how i finally solved the problem (thanks to Arthur's reply above):
public class NewSection implements EntryPoint {
private static RichTextAreaWithFormatBar rta;
private Button pseudoSubmit;
#Override
public void onModuleLoad() {
invokeExternal("hello");
rta = new RichTextAreaWithFormatBar();
pseudoSubmit = new Button(">>>");
<...>
}
<some other code here>
public static void addImage(String a) {
rta.textarea().setHTML(
rta.textarea().getHTML() + "<br /><img src=\"/cms/i/"+ a +"\" alt=\"\"><br />");
}
native void invokeExternal(String int1) /*-{
$wnd.externalJsFunction(function(int1) {
#ur.g05.smc.client.NewSection::addImage(Ljava/lang/String;)(int1);
});
}-*/;
}
And here is the "hand-written" javascript in my templates:
(first the FreeMaker code for creating the image list in that same template):
<#list images as i>
<td><img src="/cms/i/${i.keyString()}.t" alt='' onclick='addImage("${i.keyString()}.p");'/><br /><p>${i.fullWidth()}·${i.fullHeight()}</p><p>${i.previewWidth()}·${i.previewHeight()}</p><p>${i.thumbWidth()}·${i.thumbHeight()}</p></td>
</#list>
And the script itself:
<script language="javascript">
var callBackFunction;
function externalJsFunction(func) {
callBackFunction = func;
}
function addImage(imgid) {
callBackFunction(imgid);
}
</script>
What in fact happens is:
First we create a list of images, adding an "onClick" listener to each of them with the url of each corresponding image as the argument. Image urls are formed from their Keys in the datastore, plus ".t" for thumbnails, ".p" for previews and nothing for full-size images.
Each image than calls the "addImage" function. But the addImage function has to know about the textarea, which it doesn't. To that end we create the "callBackFunction" variable, and the "externalJsFunction", that sets the value of that "callBackFunction" variable. And it sets it to whatever it gets as the argument.
Now, we can call that externalJsFunction from our Widget code and pass the function that adds an image to the textarea. However, i couldn't make it work while the richtextarea was not static.
That's basically it.
And thanks for replies and votes :)

Resources