checking for element present or not using Selenium WebDriver page factory? - selenium

Checking for elements with findElements using normal WebDriver method is easy like:
boolean exists = driver.findElements( By.id("...") ).size() != 0
Elements initialized by Page Factory are like:
#FindBy(name = "filter")
private WebElement filterText;
But how can we check in our page that this element is present on the page or not ??

The isDisplayed() method should do the job:
if (filterText.isDisplayed()) {
filterText.doStuff();
}

here's something i came up with:
public boolean isElementPresent(WebElement we)
{
try {
we.getTagName();
} catch (NoSuchElementException e) {
flag = 1;
}
if (flag == 1)
return true;
else
return false;
}
which is pretty basic but effective way to do it..

Related

How do I click on an element that appears sometimes 1 or sometimes 2 at different intervals

I have done this
List<WebElement> element= driver.findElements(By.xpath(""));
for(int i=0;element.size();i++)
{
driver.findElements(By.xpath("")).isDisplayed();
driver.findElements(By.xpath("")).click();
}
I am new to java and selenium , so I thought of doing this. Is this logic correct or am I wrong? If wrong(most probably) , can you please rectify and explain alongside , wud be very helpful.
I get element not interactable error on this.
In case you are looking for method to wait for one of two elements to appear and then to click on the appeared element you can use this method:
public String waitForOneOfTwoElements(String xpath1, String xpath2){
wait = new WebDriverWait(driver, 30);
try {
wait.until(ExpectedConditions.or(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath1)),
ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath2))));
if(waitForElementToBeVisible(xpath1)){
return xpath1;
}else if(waitForElementToBeVisible(xpath2)){
return xpath2;
}
}catch (Throwable t){
return null;
}
}
Where waitForElementToBeVisible is:
public boolean waitForElementToBeVisible(String xpath) {
wait = new WebDriverWait(driver, 30);
try {
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath)));
return true;
}catch (Throwable t) {
return false;
}
}
Now, when you get the appeared element you can simply click it with:
String appearedElementXpath = waitForOneOfTwoElements(xpath1,xpath2);
driver.findElement(By.xpath(appearedElementXpath)).click();

Selenium IDE generate code not using WebDriverWait.Until

When generating NUnit code from selenium ide, wait commands like clickAndWait generate an awkward pattern using a loop.
Wouldn't it be better to use a WebDriverWait.until?
Or am I getting something wrong?
UPDATE:
Sorry, wrote from memory, the code i was referring to is on the waitForElementcommand and not clickAndWait.
This is the code i'm referring to:
// waitForElementPresent | id=id |
for (int second = 0; ; second++)
{
if (second >= 60) Assert.Fail("timeout");
try
{
if (IsElementPresent(By.Id("id"))) break;
}
catch (Exception)
{ }
Thread.Sleep(1000);
}
private bool IsElementPresent(By by)
{
try
{
driver.FindElement(by);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Reading various guides and other answers, it seems to me that a better solution would be this one:
// waitForElementPresent | id=id |
if (!WaitForElementPresent(By.Id("id"))) { Assert.Fail(); }
private bool WaitForElementPresent(By by)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
try
{
wait.Until(drv => drv.FindElement(by));
return true;
}
catch (Exception)
{
return false;
}
}
Yes, using WebDriverWait is the better approach to wait for element exist, But instead of creating own custom ExpectedConditions you should use selenium provided ExpectedConditions.ElementExists function to wait until element exist as below :-
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
IWebElement el = wait.Until(ExpectedConditions.ElementExists(by));
Hope it helps..:)

I am not able to switch to IFrame using Internet Explorer

I have developed a s keyword driven framework. It has a action keyword to switch the frame.
It works fine with Mozilla. But when it comes to IE it is not switching. It logs error.
IE driver -IEDriverServer_x64_2.44.0
IE version -9
Selenium version -selenium-java-2.44.0
Thanks in advance.
public static void switchFrame(String object,String data)throws Exception{
try{
driver.switchTo().frame("Ifrm");
Log.info("Switched the frame");
}
catch(Exception e){
Log.error("Not able to switch the frame--- " + e.getMessage());
DriverScript.bResult = false;
}
}
Here exception occurs.
I assume, the value you specified in frame is id/name/etc. You have to access the frame by calling the driver with specified value. Code would be
driver.switchTo().frame(driver.findElement(By.id("Ifrm")));
Selenium won't let me switch to the iframe by ID on Internet Explorer, but it does allow me to switch by index. If you have some sort of property that you can check that it is only available on the iframe you can do the following
new WebDriverWait(driver, 5).until(
new Predicate<WebDriver>() {
#Override
public boolean apply(WebDriver input) {
try {
int i = 1;
while (true) {
driver.switchTo().defaultContent();
driver.switchTo().frame(i);
String aClass =
driver.findElement(By.xpath("/html/body"))
.getAttribute("class");
if (aClass.contains("modal")) {
return true;
}
++i;
}
} catch (NoSuchFrameException e) {
return false;
}
}
}
);
In my case I was looking for a body class of modal

How to pass multiple locators in Selenium webdriver to fetch an element on a page

Hi can anyone pls solve this. When i write a code to automate sometimes the elements are not identified and sometimes its not found even they are present, means even if the id is present it says element not found error. So I a trying to create a method where i would pass all the dom objects i find like Ex :
public static void Click(WebDriver driver, String name,Sting linktext,Sting id,Sting Xpath,String css)
{
driver.findElement(new ByAll(By.name(name),
By.linkText(linktext),
By.id(id),
By.xpath(xpath),
By.cssSelector(css))).click();
}
And i would pass what ever value i find in source page like sometimes it will have oly id or it ll have oly link text Ex:(when i import this method in other class)
Click(Webdriver driver, "username",null,"","//[fas].user");
is this the correct way to pass the arguments. can i pass like null and "" (blank). Pls help this would become a one simple effective framework for me.
you can use this 2 methods
public static WebElement findElement(WebDriver driver, By selector, long timeOutInSeconds) {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.presenceOfElementLocated(selector));
return findElement(driver, selector);
}
public static WebElement findElementSafe(WebDriver driver, By selector, long timeOutInSeconds) {
try {
return findElement(driver, selector, timeOutInSeconds);
} catch (TimeoutException e) {
return null;
}
}
public static void waitForElementToAppear(WebDriver driver, By selector, long timeOutInSeconds, String timeOutMessage) {
try {
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
} catch (TimeoutException e) {
throw new IllegalStateException(timeOutMessage);
}
}
----------------
public static void click(WebDriver driver , By ... selector ){
for (By byPath : selector) {
WebElement element = findElementSafe(driver, byPath, 1);
if(element != null){
element.click();
}
}
}

Selenium refresh

I am working on project where everything is saved in events so it took some time for server to respond for new data. I am using Fluent wait for pages using ajax, but this one doesn't use any ajax. So I want to refresh page check if new item is there if not refresh again. How this is achieved in Selenium 2?
I did this :
def accountsAfterCreating = 0
while (accountsAfterCreating <= existingAccounts) {
driver.navigate().refresh()
WebElement table = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.className("table"))
}
})
accountsAfterCreating = table.findElements(By.className("amount")).size()
}
Is it correct way?
Use Explicit wait like this In try catch block
try{
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
}
catch()
{
driver.navigate().refresh()
}
I usually use this method to wait for any html tag. We can also specify the wait time.
public boolean waitForElement(WebElement ele, String xpath, int seconds) throws InterruptedException{
//returns true if the element appears within the time
//false when timed out
int t=0;
while(t<seconds*10){
if(ele.findElements(By.xpath(xpath)).size()>0)
return true;
else{
Thread.sleep(100);
t++;
continue;
}
}
System.out.println("waited for "+seconds+"seconds. But couldn't find "+xpath+ " in the element specified");
return false;
}
I came up with answer like this. This will work only on groovy because it is using closure
private boolean refreshUntil(Closure<Boolean> condition) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(8, TimeUnit.SECONDS)
.pollingEvery(200, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException)
wait.until(new Predicate<WebDriver>() {
boolean apply(WebDriver driver) {
driver.navigate().refresh()
if (condition()) {
return true
}
return false
}
})
return true
}
and calling this method
refreshUntil {
accountsBeforeCreation + 1 == driver.findElements(By.tagName("tr"))).size()
}