I am not able to switch to IFrame using Internet Explorer - selenium

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

Related

Selenium java SafariDriver wait for page to load after click

When I run the following code, the execution abruptly ends unless I uncomment the Thread.sleep(). As result my code in the withdraw url servlet is not executed. The click is a submit button click which loads another page.
EventFiringWebDriver webDriver = new EventFiringWebDriver(new SafariDriver());
try {
webDriver.get("http://localhost:9988");
webDriver.findElement(By.id("amount")).sendKeys(new StringBuffer().append(amount.getRupees()).append('.').append(amount.getPaise()).toString());
webDriver.findElement(By.id("withdraw")).click();
//Thread.sleep(10000);
} finally {
webDriver.close();
}
What is the right way to make selenium wait till the page loads?
I am using the following selenium version
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.11.0</version>
Sounds like explicit waits might be what you need. There are a collection of ready-to-use conditions in the ExpectedConditions class (see https://www.seleniumhq.org/docs/04_webdriver_advanced.jsp for more). But once you understand how they work, making your own is pretty straightforward. The beauty of these is that unlike Thread.sleep(), once the condition is met, it'll immediately stop waiting.
I wrote out some specific examples I've used in the past for waiting for "page loads", and then get a little into how to make your own just in case it's useful to you:
If your page is light on the ajax content, and loads some static content once, you could implement an explicit wait condition to check the DOM's readyState property
// this could benefit being static so it doesn't create new classpath defs every invocation
public ExpectedCondition<Boolean> readyStateIsComplete() {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver webDriver) {
String readyState = (String) ((JavascriptExecutor) webDriver)
.executeScript("return document.readyState");
return readyState.equals("complete");
}
public String toString() {
return "page document's readyState flag to be complete";
}
};
}
This property only is "complete" once all static content is finished loading. Using it could be like:
// prepare me like this
WebDriverWait wait = new WebDriverWait(driver, maxSecondsToWait);
// Use me like this
wait.until(readyStateIsComplete());
The example above is good for the first time you load a page before all content finishes. If your page is heavy on the ajax content, maybe instead or in addition to you could try waiting for the ajax queue to reach zero, which can be done on an already loaded page that has ajax work it is doing.
public ExpectedCondition<Boolean> activeQueuesToFinish() {
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
// This is just a formatted javascript block with in-string indenting
String jScript = "if (A4J.AJAX) {" +
" with (A4J.AJAX) {" +
" var queues = A4J.AJAX.EventQueue.getQueues();" +
" for (var queueNames in queues) {" +
" return A4J.AJAX.EventQueue.getQueue(queueNames).getSize() <= 0;" +
" }" +
" }" +
" }" +
" return true;";
try {
return (Boolean) ((JavascriptExecutor) driver).executeScript(jScript);
} catch (WebDriverException e) {
return true;
}
}
public String toString() {
return "active queues to finish.";
}
};
If you use jquery, you could try this instead for letting current ajax work finish:
public ExpectedCondition<Boolean> allAjaxRequestsFinish() {
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
return (Boolean) ((JavascriptExecutor) driver).executeScript("return jQuery.active == 0");
} catch (Exception e) {
return true;
}
}
public String toString() {
return "all ajax requests to finish.";
}
};
}
All these conditions or any condition you create in this template can be used for dynamic waiting in that same way:
wait.until(activeQueuesToFinish());
wait.until(allAjaxRequestsFinish());
Edit:
The "template" I mean is a function with this form:
public ExpectedCondition<Boolean> myCustomCondition(/* some arguments from the outside */) {
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
// Check something on the page and return either true or false,
// this method will be run repeatedly until either the time
// limit is exceeded, or true is returned
}
public String toString() {
return "a description of what this is waiting for";
}
};
}
Here's an example of how you could do this to wait on a specific element that may be holding up your page:
public ExpectedCondition<Boolean> waitForElementToHaveText(final WebElement element, final String expectedText) {
return new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
try {
return element.getText().equals(expectedText);
} catch (Exception e) {
return false; // catchall fail case
}
}
public String toString() {
return "an element to have specific text";
}
};
}

Checking a button with TestNG

I am new to the Selenium .
I need to check the availability of a button in the system and need to mark it pass and fail with AssertEquals.
Please help me .
#Test
public void sellercheck () throws InterruptedException
{
Thread.sleep(2000);
driver.findElement(By.id("UserEvent")).click();
//String r=Read.getvalue().get(0);
//select the seller
driver.findElement(By.id("LegacyNumberCriterion")).sendKeys("123456");
driver.findElement(By.id("SuperUse")).click();
System.out.println("seller number entered");
try
{
if(driver.findElements(By.id("OrganizationBranchId")).size()!=0)
{
driver.findElement(By.id("button1")).click();
}
else
{
System.out.println("The button is not available for the seller");
}
}
catch(NoSuchElementException e)
{
System.out.println("Element does not exist!");
}
}
You can choose from following 2 solutions which suitable to you:
1] Code to check element present or not using assertion in Selenium Webdriver would be something like this:
assertTrue(!isElementPresent(By.id("id of button")));
2] This assertion verifies that there are no matching elements in the DOM and returns the value of Zero, so the assertion passes when the element is not present. Also it would fail if it was present.
Assert.assertEquals(0, driver.findElement(By.id("id of button")).size());
Try this solution and let me know if it works.
Try this piece of code with some simple tweaks to your own code:
WebDriver driver;
#Test
public void sellercheck () throws InterruptedException
{
Thread.sleep(2000);
driver.findElement(By.id("UserEvent")).click();
//String r=Read.getvalue().get(0);
//select the seller
driver.findElement(By.id("LegacyNumberCriterion")).sendKeys("123456");
driver.findElement(By.id("SuperUse")).click();
System.out.println("seller number entered");
try
{
if(driver.findElements(By.id("OrganizationBranchId")).size()!=0)
{
driver.findElement(By.id("button1")).click();
}
else
{
System.out.println("The button is not available for the seller");
}
}catch(NoSuchElementException e)
{
System.out.println("Element does not exist!");
}
}
Let me know if this works for you or update me the error you see.

Error in extension for webdriver

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());
}

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();
}
}
}

How to deal with ModalDialog using selenium webdriver?

I am unable to switch to Modal Dialog of given example
http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/showModalDialog2.htm
I don't know how to get element on modal Dialog
Use
following methods to switch to modelframe
driver.switchTo().frame("ModelFrameTitle");
or
driver.switchTo().activeElement()
Hope this will work
What you are using is not a model dialog, it is a separate window.
Use this code:
private static Object firstHandle;
private static Object lastHandle;
public static void switchToWindowsPopup() {
Set<String> handles = DriverManager.getCurrent().getWindowHandles();
Iterator<String> itr = handles.iterator();
firstHandle = itr.next();
lastHandle = firstHandle;
while (itr.hasNext()) {
lastHandle = itr.next();
}
DriverManager.getCurrent().switchTo().window(lastHandle.toString());
}
public static void switchToMainWindow() {
DriverManager.getCurrent().switchTo().window(firstHandle.toString());
Try the below code. It is working in IE but not in FF22. If Modal dialog found is printed in Console, then Modal dialog is identified and switched.
public class ModalDialog {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
WebDriver driver = new InternetExplorerDriver();
//WebDriver driver = new FirefoxDriver();
driver.get("http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/showModalDialog2.htm");
String parent = driver.getWindowHandle();
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement push_to_create = wait.until(ExpectedConditions
.elementToBeClickable(By
.cssSelector("input[value='Push To Create']")));
push_to_create.click();
waitForWindow(driver);
switchToModalDialog(driver, parent);
}
public static void waitForWindow(WebDriver driver)
throws InterruptedException {
//wait until number of window handles become 2 or until 6 seconds are completed.
int timecount = 1;
do {
driver.getWindowHandles();
Thread.sleep(200);
timecount++;
if (timecount > 30) {
break;
}
} while (driver.getWindowHandles().size() != 2);
}
public static void switchToModalDialog(WebDriver driver, String parent) {
//Switch to Modal dialog
if (driver.getWindowHandles().size() == 2) {
for (String window : driver.getWindowHandles()) {
if (!window.equals(parent)) {
driver.switchTo().window(window);
System.out.println("Modal dialog found");
break;
}
}
}
}
}
Solution in R (RSelenium):
I had a popup dialog (which is dynamically generated) and hence undetectable in the original page source code
Here are methods which worked for me:
Method 1: Simulating Pressing keys for Tabs and switching to that modal dialog
My current key is focussed on a dropdown button behind the modal dialog box
remDr$sendKeysToActiveElement(list(key = "tab"))
Sys.sleep(5)
remDr$sendKeysToActiveElement(list(key = "enter"))
Sys.sleep(15)
Method 2: Bring focus to the frame(or iframe) if you can locate it
date_filter_frame <- remDr$findElement(using = "tag name", 'iframe')
date_filter_frame$highlightElement()
Sys.sleep(5)
remDr$switchToFrame(date_filter_frame)
Sys.sleep(2)
Now you can search for elements in the frame. Remember to put adequate Sys.sleep in between commands for elements to load properly (just in case)
date_filter_element <- remDr$findElement(using = "xpath", paste0("//*[contains(text(), 'Week to Date')]"))
date_filter_element$highlightElement()
Try this code, include your object names & variable to work.
Set<String> windowids = driver.getWindowHandles();
Iterator<String> iter= windowids.iterator();
for (int i = 1; i < sh.getRows(); i++)
{
while(iter.hasNext())
{
System.out.println("Main Window ID :"+iter.next());
}
driver.findElement(By.id("lgnLogin_UserName")).clear();
driver.findElement(By.id("lgnLogin_UserName")).sendKeys(sh.getCell(0,
i).getContents());
driver.findElement(By.id("lgnLogin_Password")).clear();
driver.findElement(By.id("lgnLogin_Password")).sendKeys(sh.getCell(1,
i).getContents());
driver.findElement(By.id("lgnLogin_LoginButton")).click();
Thread.sleep(5000L);
windowids = driver.getWindowHandles();
iter= windowids.iterator();
String main_windowID=iter.next();
String tabbed_windowID=iter.next();
System.out.println("Main Window ID :"+main_windowID);
//switch over to pop-up window
Thread.sleep(1000);
driver.switchTo().window(tabbed_windowID);
System.out.println("Pop-up window Title : "+driver.getTitle());
I have tried it, it works for you.
String mainWinHander = webDriver.getWindowHandle();
// code for clicking button to open new window is ommited
//Now the window opened. So here reture the handle with size = 2
Set<String> handles = webDriver.getWindowHandles();
for(String handle : handles)
{
if(!mainWinHander.equals(handle))
{
// Here will block for ever. No exception and timeout!
WebDriver popup = webDriver.switchTo().window(handle);
// do something with popup
popup.close();
}
}
Assuming the expectation is just going to be two windows popping up (one of the parent and one for the popup) then just wait for two windows to come up, find the other window handle and switch to it.
WebElement link = // element that will showModalDialog()
// Click on the link, but don't wait for the document to finish
final JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript(
"var el=arguments[0]; setTimeout(function() { el.click(); }, 100);",
link);
// wait for there to be two windows and choose the one that is
// not the original window
final String parentWindowHandle = driver.getWindowHandle();
new WebDriverWait(driver, 60, 1000)
.until(new Function<WebDriver, Boolean>() {
#Override
public Boolean apply(final WebDriver driver) {
final String[] windowHandles =
driver.getWindowHandles().toArray(new String[0]);
if (windowHandles.length != 2) {
return false;
}
if (windowHandles[0].equals(parentWindowHandle)) {
driver.switchTo().window(windowHandles[1]);
} else {
driver.switchTo().window(windowHandles[0]);
}
return true;
}
});
Nope, Model window needs to be handle by javaScriptExecutor,Because majorly model window made up of window model,
This will works once model appeared then control take a place into model and click the expected element.
have to import javascriptexector
like below,
Javascriptexecutor js =(Javascriptexecutor).driver;
js.executescript(**<element to be clicked>**);
P.S. 1 adding my 2 cents even though the question is too old
public void PressEnterKey()
{
var simulator = new InputSimulator();
simulator.Keyboard.KeyPress(VirtualKeyCode.RETURN);
}
you can create a method like the above and call it where it is required.
P.S. 2 - you can change the keyboard inputs as well (like up arrow, down arrow, page down etc)