I'm writing a framework with page object. I have a lot of ajax, so in order to get rid of ugly Thread.sleep(5000), I created an extension method, which waits until an element is visible and clicks on it, otherwise it throws an error. But I suspect that there is an error in my code, because it always thrown an error.
public static void WaitForVisible(this IWebElement element, int timeoutSec = 10)
{
var startTime = DateTime.Now;
while ((DateTime.Now - startTime) > TimeSpan.FromSeconds(timeoutSec))
{
if (element.Displayed)
return;
}
throw new Exception("Element wasn't displayed after '" + timeoutSec + "'!");
}
public static void ClickWithWait(this IWebElement element)
{
WaitForVisible(element);
element.Click();
}
Could you please tell what am I doing wrong?
Please try this method.
WebDriverWait wait = new WebDriverWait(driver, 10);
try {
WebElement element= wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("someid")));
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
Related
#Test
public void testHeaderlinks() throws IOException {
homePage=new HomePage();
homePage.ClickmenuHolidays();
homePage.Clickmenuattraction();
homePage.Clickmenuhotdeal();
String originalHandle = driver.getWindowHandle();
for(String handle : driver.getWindowHandles()) {
if (!handle.equals(originalHandle)) {
driver.switchTo().window(handle);
driver.close();
}
}
driver.switchTo().window(originalHandle);
}
public static void Takescreenshot(String filename) throws IOException {
File file= ((TakesScreenshot))driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file,new File("C:\\Users\\User\\Desktop\\POMMabuhayFinal\\src\\main\\java\\Screnshots\\"+filename+".jpg"));
}
In my code i am click hyperlinks in new tab and close those tabs (closing all tabs after all hyperlinks clicks)
My question is how can i take screenshot of opened tabs( i wanna take all new tabs which are open)
Use WebDriverWait to wait for tab/page load and then call your Takescreenshot method while you iterate tabs
#Test
public void testHeaderlinks() throws IOException {
homePage=new HomePage();
homePage.ClickmenuHolidays();
homePage.Clickmenuattraction();
homePage.Clickmenuhotdeal();
String originalHandle = driver.getWindowHandle();
int count = 1;
for(String handle : driver.getWindowHandles()) {
if (!handle.equals(originalHandle)) {
// Initialize WebDriverWait with 15 secs wait timeout or expected wait timeout
WebDriverWait wait = new WebDriverWait(myDriver, 15);
// Wait for page to load
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));
driver.switchTo().window(handle);
// Take screenshot of your current tab
Takescreenshot("tabImage" + String.valueOf(count)) // You can use your own imageName
driver.close();
count++;
}
}
driver.switchTo().window(originalHandle);
}
public static void Takescreenshot(String filename) throws IOException {
File file= ((TakesScreenshot))driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file,new File("C:\\Users\\User\\Desktop\\POMMabuhayFinal\\src\\main\\java\\Screnshots\\"+filename+".jpg"));
}
Please Try this
public void TakeScreenShot()
{
try
{
string text = AppDomain.CurrentDomain.BaseDirectory + "\\screenshots\\";
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
if (Directory.Exists(text))
{
string text2 = text + XYZ+ ".jpeg";
if (File.Exists(text2))
{
File.Delete(text2);
}
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(text2, ScreenshotImageFormat.Jpeg);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Here i'm getting all checkboxes of a page but unable to select all check boxes when i tried below code its giving error.Here is my code
public class AllCheckBoxes {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.flipkart.com/mobiles/pr?p%5B%5D=facets.brand%255B%255D%3DSamsung&sid=tyy,4io&otracker=nmenu_sub_electronics_0_Samsung");
Thread.sleep(1000);
try {
// Option 1
List<WebElement> CHECKBOXlist = driver.findElements(By.xpath("//input[#type='checkbox']"));
// Option 2
//List<WebElement> CHECKBOXlist = driver.findElements(By.cssSelector("[type='checkbox']"));
System.out.println("Total Check Boxes are avaliable here are: "+CHECKBOXlist.size());
for (WebElement checkbox : CHECKBOXlist) {
checkbox.click();
}
} catch (Exception e) {
System.out.println(e.getMessage());
// Error as: Element is no longer attached to the DOM
// For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
}
driver.quit();
}
}
Can anybody guide me how to do this?
A stale element exception usually occurs when you are trying to interact with a web element from a previous page instance. Perhaps one of these checkboxes you are ticking does something like reload the page, if this is the case, then the remaining checkboxes to click will fail.
Edit: Yes this does seem to be the case after visiting the webpage you are trying to use in your code. My suggestion would be to use indexing within an XPath to get the checkboxes one at a time:
public class AllCheckBoxes {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.flipkart.com/mobiles/pr?p%5B%5D=facets.brand%255B%255D%3DSamsung&sid=tyy,4io&otracker=nmenu_sub_electronics_0_Samsung");
Thread.sleep(1000);
try {
// Option 1
List<WebElement> CHECKBOXlist = driver.findElements(By.xpath("//input[#type='checkbox']"));
// Option 2
//List<WebElement> CHECKBOXlist = driver.findElements(By.cssSelector("[type='checkbox']"));
System.out.println("Total Check Boxes are avaliable here are: "+CHECKBOXlist.size());
// this for loop will account for page loads:
for (int i = 0; i < CHECKBOXlist.size(); i++) {
driver.findElement(By.xpath("(//input[#type='checkbox'])[" + (i+1) + "]")).click();
}
} catch (Exception e) {
System.out.println(e.getMessage());
// Error as: Element is no longer attached to the DOM
// For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
}
driver.quit();
}
}
So basically, you're going to have to find the checkboxes individually rather than all at once to account for page reloading.
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
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();
}
}
}
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()
}