NoSuchWindowException when trying to get a report inside a new window - selenium

I have the following in my code:
withWindow({ title == 'Google' }) {
report "08"
}
And report is leading me to the exception NoSuchWindowException. I've checked if that was a problem of the Window selector and it isn't,After some research I guessed that the problem was that the driver got messed in the way so I stored and switched my driver:
String mainHandle= driver.getWindowHandle();
driver.switchTo().window('Google');
But I kept getting the same error. So I tried:
driver.get("http://www.google.com");
And it is working but I need to do this dinamycally and automatically because the windows and popups that we are working with are hundreds and with different titles.
How can I achieve that in every windows that opens? We are generating the code with a external tool so I don't need to do "magic", only a driver.get.windowUrl or something like this will work for me, I will add the concurrence later.

If you want to get the last window handle that is opened, you can do something like this:
public String getLastWindowHandle() {
Set<String> windows = webDriver.getWindowHandles();
Iterator<String> itera = windows.iterator();
String window = null;
while (itera.hasNext()) {
window = itera.next();
}
return window;
}
with this handle, you can switch to the new window:
webDriver.switchTo().window(getLastWindowHandle());

Related

Selenium WebDriver - Chrome issue [duplicate]

This question already has an answer here:
Best way to keep track and iterate through tabs and windows using WindowHandles using Selenium
(1 answer)
Closed 2 years ago.
Im wokring on a tool development that tests various services on Chrome browser. For each service I would need to launch a new tab on Chrome. I use the below code,
The first 2 new tabs works fine, when the 3rd tab is launched, the 1st tab's url is navigated to the one used for 3rd tab.
Not sure what's messing up. Need assistance!
I believe when your loop enters second iteration, your if statement executes to true.
You can just do following:
for(String actual: handles){
driver.switchTo().window(actual);
}
After execution of the above loop, your script will always point to last window opened.
Then you can do:
driver.get(URL + service + URL_);
outside the loop.
P.S.: If required, for more enhancement you can use below script:
private void switchToLatestBrowserWindow(WebDriver driver, Set<String> priorHandles)
{
new WebDriverWait(driver, 60).until( // keep trying to switch for 60 seconds
d -> {
Set<String> newHandles = d.getWindowHandles();
if (newHandles.size() != priorHandles.size()) {
log.Info("NewHandles Size not equal to PriorHandles size.");
String lastWindowHandle = "";
for (String windowHandle : newHandles) {
lastWindowHandle = windowHandle;
}
log.Info("LastWindowHandle Id: " + lastWindowHandle);
d.switchTo().window(lastWindowHandle);
log.Info("Switched window to " + lastWindowHandle);
return true;
} else {
return false;
}
});
}
priorHandles is set of window handles retrieved before opening new window. (the first line of code, in your case). So complete snippet would look like:
Set<String> priorHandles = driver.getWindowHandles();
((JavasriptExecutor) driver).executeScript( script: "window.open()");
switchToLatestBrowserWindow(driver, priorHandles);
driver.get(URL + service + URL_);

WinAppDriver having issues identify elements in a driver when the driver changes too much

For example: Launch Outlook on your desktop. Notice how there is a "splash loading screen" well the driver I have will look at this executable and wait x seconds before trying to click on the "New Email" button. However when it gets to the page where the new email button appears, it can't find it. Strange... hmm okay lets start the application but have it trigger the executable that is already in the process. It looks for the new email button and finds it no problem.
The only thing i can think of is that the driver loads the executable, the executable then changes its data drastically or something. Then all of a sudden i need to build a new driver. But I dont think this is the way to go about it.
[TestInitialize]
public void TestMethod1()
{
options.AddAdditionalCapability("app", #"C:\Program Files (x86)\<PATH>");
_driver = new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), options);
System.Threading.Thread.Sleep(5000);
}
[TestMethod]
public void TEST()
{
LoginPage page = new LoginPage(new WindowsDriver<WindowsElement>(new Uri("http://127.0.0.1:4723"), options)); // Notice how i am building a new driver just for this page. This is VERY heavy.
page.Login("USERNAME", "PASSWORD");
}
You probably have the "splash screen issue".
Here's a explantation about what to do about it.
In short, winappdriver creates a new windowhandle for every new window it encounters. As the splash screen counts for a separate window, you should have 2 windowhandles available at the moment you wanted to click that "new email" button. The most recent windowhandle will be the highest index.
You can switch between windowhandles like this (copied from link):
// Return all window handles associated with this process/application.
// At this point hopefully you have one to pick from. Otherwise you can
// simply iterate through them to identify the one you want.
var allWindowHandles = session.WindowHandles;
// Assuming you only have only one window entry in allWindowHandles and it is in fact the correct one,
// switch the session to that window as follows. You can repeat this logic with any top window with the same²
// process id (any entry of allWindowHandles)
session.SwitchTo().Window(allWindowHandles[0]);
Also take a look at this answer. Could be useful too.

Source not available for newly opened window - Selenium Webdriver

Im trying to automate a Web Application through Selenium. But at a point Im getting stuck. Problem is that when I open a page and click on Search (to load all the existing saved data), a new window opens where the F12 option is not working neither can I right click on that window and select view source. If I could get the source of that window, I can use window handle. Can anybody help me to resolve this?
In my project I use something like this to a pop-up window:
public void switchToWindowOtherThan(String windowHandle) {
try {
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(windowHandle)) {
driver.switchTo().window(handle);
}
}
} catch (NoSuchWindowException nwe) {
//handle exception
}
}
In my code I would use it as follows:
switchToWindowOtherThan(driver.getWindowHandle());

'sendKeys' are not working in Selenium WebDriver

I am not able to put any value in my application using WebDriver. My application is using frames.
I am able to clear the value of my textbox with driver.findElement(By.name("name")).clear();, but I'm unable to put any value using driver.findElement(By.name("name")).sendKeys("manish");. The click command works for another button on the same page.
I also had that problem, but then I made it work by:
myInputElm.click();
myInputElm.clear();
myInputElm.sendKeys('myString');
Before sendkeys(), use the click() method (i.e., in your case: clear(), click(), and sendKeys()):
driver.findElement(By.name("name")).clear();
driver.findElement(By.name("name")).click(); // Keep this click statement even if you are using click before clear.
driver.findElement(By.name("name")).sendKeys("manish");
Try clicking on the textbox before you send keys.
It may be that you need to trigger an event on the field before input and hopefully the click will do it.
I experienced the same issue and was able to collect the following solution for this:
Make sure element is in focus → try to click it first and enter a string.
If there is some animation for this input box, apply some wait, not static. you may wait for an element which comes after the animation. (My case)
You can try it out using Actions class.
Clicking the element works for me too, however, another solution I found was to enter the value using JavaScript, which doesn't require the element to have focus:
var _element= driver.FindElement(By.Id("e123"));
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].setAttribute('value', 'textBoxValue')", _element);
Use JavaScript to click in the field and then use sendkeys() to enter values.
I had a similar problem in the past with frames. JavaScript is the best way.
First pass the driver control to the frame using:
driver.switchTo().frame("pass id/name/index/webelement");
After that, perform the operation which you want to do on the webelement present inside the frame:
driver.findElement(By.name("name")).sendKeys("manish");
I have gone with the same problem where copy-paste is also not working for that text box.
The below code is working fine for me:
WebDriver driver = new FirefoxDriver();
String mobNo = "99xxxxxxxx";
WebElement mobileElementIrs =
driver.findElement(By.id("mobileNoPrimary"));
mobileElementIrs.click();
mobileElementIrs.clear();
mobileElementIrs.sendKeys(mobNo);
I had a similar problem too, when I used
getDriver().findElement(By.id(idValue)).clear();
getDriver().findElement(By.id(idValue)).sendKeys(text);
The value in "text" was not completely written into the input. Imagine that "Patrick" sometimes write "P" another "Pat",...so the test failed
The fix is a workaround and uses JavaScript:
((JavascriptExecutor)getDriver()).executeScript("$('#" + idValue + "').val('" + value + "');");
Now it is fine.
Instead of
driver.findElement(By.id("idValue")).sendKeys("text");
use,
((JavascriptExecutor)getDriver()).executeScript("$('#" + "idValue" + "').val('" + "text" + "');");
This worked for me.
I had a similar problem recently and tried some of the suggestions above, but nothing worked. In the end it fell back on a brute-force retry which retries if the input box wasn't set to what was expected.
I wanted to avoid thread.sleep for obvious reasons and saw different examples of it failing that looked like some kind of race or timing condition.
public void TypeText(string id, string text)
{
const int numberOfRetries = 5;
for (var i = 1; i < numberOfRetries; i++)
{
try
{
if (TryTypeText())
return;
}
catch (Exception)
{
if (i == numberOfRetries)
throw;
}
}
bool TryTypeText()
{
var element = _webDriver.FindElement(By.Id(id));
element.Click();
element.Clear();
element.SendKeys(text);
if (element.TagName.ToLower() == "input"
&& !DoesElementContainValue(element, text, TimeSpan.FromMilliseconds(1000)))
{
throw new ApplicationException($"Unable to set the type the text '{text}' into element with id {id}. Value is now '{element.GetAttribute("value")}'");
}
return true;
}
}
private bool DoesElementContainValue(IWebElement webElement, string expected, TimeSpan timeout)
{
var wait = new WebDriverWait(_webDriver, timeout);
return wait.Until(driver =>
{
try
{
var attribute = webElement.GetAttribute("value");
return attribute != null && attribute.Contains(expected);
}
catch (StaleElementReferenceException)
{
return false;
}
});
}
In my case, I had some actions.keyDowns(Keys.CONTOL).XXXX;
But I forgot to add the keyUp for that button and that prevented from sending keys and resulted in weird behaviors
Adding X.keyUp() after the x.keyDown() fixed the issue
Try using JavaScript to sendkeys().
WebElement element = driver.findElement(By.name("name"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
More information on JavaScript Executor can be found at
JavascriptExecutor - Selenium.
Generally I keep a temporary variable. This should work.
var name = element(by.id('name'));
name.clear();
name.sendKeys('anything');

Switching to a window with no name

Using the Codeception testing framework and Selenium 2 module to test a website, I end up following a hyperlink that opens a new window with no name. As a result the switchToWindow() function will not work because it is trying to switch to the parent window (which I'm currently on). Without being able to switch to the new window I cannot perform any testing on it.
<a class="external" target="_blank" href="http://mylocalurl/the/page/im/opening">
View Live
</a>
Using both Chrome and Firefox debugging tools I can confirm the new window doesn't have a name, and I cannot give it one because I cannot edit the HTML page I am working on. Ideally I would have changed the HTML to use javascript onclick="window.open('http://mylocalurl/the/page/im/opening', 'myPopupWindow') however this is not possible in my case.
I've looked around on the Selenium forums without any clear method to tackle this problem, and Codeception doesn't appear to have much functionality around this.
After searching around on the Selenium forum and some helpful prods from #Mark Rowlands, I got it to work using raw Selenium.
// before codeception v2.1.1, just typehint on \Webdriver
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
$handles=$webdriver->window_handles();
$last_window = end($handles);
$webdriver->focusWindow($last_window);
});
Returning back to the parent window was easy because I could just use Codeception's switchToWindow method:
$I->switchToWindow();
Building on the accepted answer, in Codeception 2.2.9 I was able to add this code to the Acceptance Helper and it seems to work.
/**
* #throws \Codeception\Exception\ModuleException
*/
public function switchToNewWindow()
{
$webdriver = $this->getModule('WebDriver')->webDriver;
$handles = $webdriver->getWindowHandles();
$lastWindow = end($handles);
$webdriver->switchTo()->window($lastWindow);
}
Then in the test class I can do this:
$I->click('#somelink');
$I->switchToNewWindow();
// Some assertions...
$I->switchToWindow(); // this switches back to the previous window
I had a heck of a time trying to figure out how to do this by just searching google, so I hope it helps someone else.
Try this,
String parentWindowHandle = browser.getWindowHandle(); // save the current window handle.
WebDriver popup = null;
Iterator<String> windowIterator = browser.getWindowHandles();
while(windowIterator.hasNext()) {
String windowHandle = windowIterator.next();
popup = browser.switchTo().window(windowHandle);
}
make sure to return on parent window using,
browser.close(); // close the popup.
browser.switchTo().window(parentWindowHandle); // Switch back to parent window.
I hope will help you.
Using Codeception 2.2+ it looks like this:
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webdriver) {
$handles = $webdriver->getWindowHandles();
$lastWindow = end($handles);
$webdriver->switchTo()->window($lastWindow);
});