I am following Page Object Model to automate a flow in one application. In one of the module I have to add a new post which have a "Title" and a "Body" field. As of now, I am able to send the text in the "Title" field as it is in the Top Window. But the "Body" is within an iframe. After passing the text in "Title" I tried to switch to the iframe before writing in the "Body". This piece of code I have written in the main file. But Selenium shows an error as org.openqa.selenium.ElementNotVisibleException: element not visible
My PageFactory code is as follows:
package com.wordpress.pom.Pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
public class AddNewPost {
WebDriver driver;
public AddNewPost(WebDriver addNewPostDriver)
{
this.driver=addNewPostDriver;
}
@FindBy(how=How.ID,using="title")
WebElement post_title;
@FindBy(how=How.XPATH,using=".//*[@id='tinymce']/p/br")
WebElement post_body;
public void construct_title()
{
post_title.sendKeys("This is the Title");
System.out.println("Title written");
}
public void construct_body()
{
post_body.sendKeys("This is the body");
System.out.println("Body written");
}
}
I am using testNG to schedule the testcases. Here is my main file code:
package com.wordpress.pom.Testcase;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.wordpress.pom.Helper.BrowserFactory;
import com.wordpress.pom.Pages.AddNewPost;
import com.wordpress.pom.Pages.Dashboard;
import com.wordpress.pom.Pages.LoginPageNew;
import com.wordpress.pom.Pages.Posts;
public class VerifyValidLogin
{
WebDriver driver;
//code ommitted
@Test (priority=3)
public void construct_title()
{
//Created Page Object using Page Factory
AddNewPost add_new_post = PageFactory.initElements(driver, AddNewPost.class);
//Call the method
add_new_post.construct_title();
}
@Test (priority=4)
public void construct_body()
{
//Created Page Object using Page Factory
AddNewPost add_new_post = PageFactory.initElements(driver, AddNewPost.class);
driver.switchTo().frame("content_ifr");
//Call the method
add_new_post.construct_body();
}
}
The HTML DOM is as:
<iframe id="content_ifr" src="javascript:""" allowtransparency="true" title="Rich Text Area Press ALT F10 for toolbar. Press ALT 0 for help." style="width: 100%; height: 330px; display: block;" frameborder="0">
<!DOCTYPE >
<html>
<head xmlns="http://www.w3.org/1999/xhtml">
<body id="tinymce" class="mceContentBody content post-type-post wp-editor" onload="window.parent.tinyMCE.get('content').onLoad.dispatch();" dir="ltr" contenteditable="true">
<p>
<br data-mce-bogus="1">
</p>
</body>
</html>
</iframe>
I feel the elements identified in the PageFactory for the body is not incorrect. Can someone help me out please?
Update:
Add a Thread.sleep(3000) in the main class before switching to the iframe.
Thread.sleep(3000); driver.switchTo().frame("content_ifr");
Changed the XPATH of the "Body" field in Page Factory.
@FindBy(how=How.XPATH,using="//html/body/p") WebElement post_body;
On debugging found that WebDriver does clicks on the Body field and I can sysout but won't send the keys in the Body field. So I was forced to use Action class.
public void construct_body() { Actions actions = new Actions(driver); actions.moveToElement(post_body); actions.click(); actions.sendKeys("Some Name"); actions.build().perform(); System.out.println("Body written"); }
I am able to pass the text now. But I am still not sure why would I need the Action class even after clicking on the Body element. Finally would like your opinion if my approach is correct here following the Page Object Model.