Frame is like a window within a window on a webpage.Sometimes when we click a sigh in button a new box open in the same window.When we use xpath to send keys to username and password field code throws exceptions like element not found etc But xpath looks ok .We can then inpect the form fields to check if its a frame.So the problem is we have to move the control to that frame to access that partiucular xpath.There may be n no of frames on a webpage,So what frame number is it where we want to access the xpath i.e on which frame is our dialog box present,this is not easy to find. First way is to ask the developer on which page is the frame present If we can't reach the developer then we have to use a hit and trail method that we used in our code here
int size = driver.findElements(By.tagName("iframe")).size(); //To find total number of frames on a webpage
//Then we can iterate throw each frame
for(int i=0;i<size;i++){
//go to first frame
driver.switchTo().frame(i);
//See if this first frame has any elements with given xpath.If this frame has any elment with that xpath then its size will be 1
int numberOfElements = driver.findElements(By.xpath("//*[@id='input_0']")).size();
System.out.println("This frame has number of elements we are looking for = "+numberOfElements);
//after checking frame 1 go to main window as we cant go from one frame to another.We can only go from frame to main window and then to next //frame
driver.switchTo().defaultContent();
driver.switchTo().frame(4); //After we find the frame which has that xpath we go to that frame
driver.findElement(By.xpath("//*[@id='input_0']")).sendKeys("abc"); pass the data
driver.switchTo().defaultContent(); //Go back to main window again
We can even write a custom function for above that returns the frame number containing given element
public static int findFrameNumber(int noOfFrames,String xpath){
int frameContainingElements;
for(int i=0;i<noOfFrames;i++){
driver.switchTo().frame(i);
int noOfElements = driver.findElements(By.xpath(xpath)).size();
driver.switchTo().defaultContent();
if(numberOfElements==1){
frameContainingElements=i;
break;
}
}
return frameContainingElements;
}
}