Selenium 4 C# Edge IEMode - WindowHandles funtion does not increase number of handles when new browser window appears - selenium

I updated Selenium to 4. I test legacy app that runs only on IE. Now IE will be closed down and I need to switch to MS Egde in capability mode.
My tests during execution need to switch to new browser windows and uses function IWebDriver.WindowHandles to do it (code below).
I had to add new options for a driver to run test on Edge like this:
var options = new InternetExplorerOptions();
options.AttachToEdgeChrome = true;
options.EdgeExecutablePath = #"\msedge.exe";
Then I use code like this to switch between browser windows:
public Context SwitchToNewIEWindow(string windowTitle, bool isEqual = true)
{
for (int i = 0; i < context.GetTimeout().Seconds; i++)
{
try
{
var ieWindowHandlers = context.GetDriver().WindowHandles;
foreach(var handler in ieWindowHandlers)
{
var window = context.GetDriver().SwitchTo().Window(handler);
bool condition = isEqual ? window.Title == windowTitle : window.Title.Contains(windowTitle);
if (condition)
{
context.SetDriver(window);
context.SetCurrentWindow(windowTitle);
return context;
}
}
}
catch (Exception)
{
context.Wait(1);
}
}
throw new Exception($"No window found with title: {windowTitle}");
}
In Selenium 3 everything works fine and WindowHandles function returns 2 handles. In Selenium 4 and IEDriver in Edge mode this function returns 1 handle.I have read https://github.com/SeleniumHQ/selenium/issues/8868 but in my case waiting a few seconds does not change anything. Even after a minute I still get only handle of first window.
Any suggestions how to make it work properly again in Selenium 4.
Libraries and its versions:

Related

Problem with comparing screenshots using selenium

I want to cover ui test cases with automation and was suggested to imply compare screenshots
So the algorithm is the following:
1.I take screenshot of the page using selenium takescreenshot method and stored it in expected results folder
2.That I'm running test case which take screenshot of the same page and then compare it with expected screenshot from the step1
I was using the following method:
try {
// take buffer data from both image files //
BufferedImage biA = ImageIO.read(fileA);
DataBuffer dbA = biA.getData().getDataBuffer();
int sizeA = dbA.getSize();
BufferedImage biB = ImageIO.read(fileB);
DataBuffer dbB = biB.getData().getDataBuffer();
int sizeB = dbB.getSize();
// compare data-buffer objects //
if (sizeA == sizeB) {
for (int i = 0; i < sizeA; i++) {
if (dbA.getElem(i) != dbB.getElem(i)) {
return false;
}
}
return true;
} else {
return false;
}
} catch (Exception e) {
LOGGER.error("Failed to compare image files");
return false;
}
And previous week it was working well, but today I ran the same test and it failed, I opened images properties and see that screenshot made today is larger by 0,1 KB then the expected one.
Can't understand the reason
Can it be somehow related to chrome constant background updates and for example browser has some update during the weekend and now the screenshot is little bit different and this way of comparing is wrong?
And if yes, then how can wee do this, I tried popular library Ashot and it also tells me that the screenshot are different

I wrote a function for window handling but it's not working in selenium webdriver

I am working on Selenium webdriver and I have write a function for window handling. I have written code for naukri.com popup handling. My scenario is to Open the naukri.com and without closing popup window. I want to switch main window and click on Login button.I have written the code and created a function. when I am running the script focus is going on main page and url is displayed as selected but I am not able to click on Login button. I am not understanding where the problem is.Please suggest me.
public static WebDriver fn_SetFocus_According_Title(WebDriver dObj, String arg_title)
{
Set<String> setcol_windowHandle=dObj.getWindowHandles();
Iterator<String>itcol_handleval=setcol_windowHandle.iterator();
while(itcol_handleval.hasNext()==true){
String windowhanldval=itcol_handleval.next();
dObj=dObj.switchTo().window(windowhanldval);
String apptitle=dObj.getTitle();
if(apptitle.contains(arg_title))
{
dObj=dObj.switchTo().window(arg_title);
}
}
return dObj;
}
}
WebDriver dObj = new FirefoxDriver();
dObj.manage().window().maximize();
dObj.get("https://www.naukri.com");
dObj.manage().timeouts().implicitlyWait(60,TimeUnit.SECONDS);
dObj=fn_SetFocus_According_Title(dObj,"Jobs - Recruitment - Job Search - Employment - Job Vacancies - Naukri.com");
dObj.findElement(By.xpath("//a[#id='login_Layer']")).click();
Make the following changes in your code:
Change to:
dObj.switchTo().window(windowhanldval);
Reduce the actual string of "arg_title" as you would be looking for this entire string within the String obtained by getTitle()
When you are already on that page trying to match the page title which means the focus is already on the actual page where we need to locate the Login button element. So remove the second switch () line entirely. Rather use "break" to come out if loop.
Let me know if these steps works for you.
The function below works for me.
public static void switchToWindow(String windowTitle)
{
for (String window : driver.getWindowHandles())
{
driver.switchTo().window(window);
if (driver.getTitle().equals(windowTitle))
{
return;
}
}
throw new InvalidParameterException("The window titled <" + windowTitle + "> does not exist.");
}
One issue you may run into is that when a new tab/window is created, you may need to wait for it to appear. To do that, you can use something like
int count = driver.getWindowHandles().size() + 1; // add 1 to the current window count
// do something that spawns a new window
new WebDriverWait(driver, 3).until(ExpectedConditions.numberOfWindowsToBe(count));
You don't need to return the WebDriver instance. It's the same driver instance you are already using. If the expected window title is not found, the function will throw an exception.
Hope this will work for you.
public void Parenthandle(WebDriver wb){
try {
String ParentPageHandle = wb.getWindowHandle();
for (String newPage : wb.getWindowHandles()) {
if (!ParentPageHandle.equals(newPage)) {
wb.switchTo().window(newPage);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
}

any waitForJs function to wait for some javascript code returns true

This is question about golang selenium webdriver.
Is there any function that returns only after some js code return true.
var session *webdriver.Session
...
session.waitForJs(`$('#redButton').css('color')=='red'`)
// next code should be executed only after `#redButton` becomes red
The problem is that method session.waitForJs do not exist.
I don't see any wait functions in the golang bindings to Selenium, so you'll most likely need to define your own. This is my first attempt at golang, so bear with me:
type elementCondition func(e WebElement) bool
// Function returns once timeout has expired or the element condition is true
func (e WebElement) WaitForCondition(fn elementCondition, int timeOut) {
// Loop if the element condition is not true
for i:= 0; !elementCondition(e) && i < timeOut; i++ {
time.sleep(1000)
}
}
There are two options to define the elementCondition. Your method of using Javascript looks like it could work with the ExecuteScript function documented in webdriver.go
// Inject a snippet of JavaScript into the page for execution in the
context of the currently selected frame. The executed script is
assumed to be synchronous and the result of evaluating the script is
returned to the client.
An alternative is to access the element properties through Selenium
func ButtonIsRed(WebElement e) (bool) {
return (e.GetCssProperty('color') == 'red')
}
So your code would become
var session *webdriver.Session
....
// Locate the button with a css selector
var webElement := session.FindElement(CSS_Selector, '#redButton')
// Wait for the button to be red
webElement.WaitForCondition(ButtonIsRed, 10)

Best way to find out if jqGrid is loaded and ready with Selenium

How are you finding out if jqGrid is loaded and ready to be used, via selenium.
Some details :
Im using C# driver
I have a method : new WebDriverWait(driver, new TimeSpan(0, 0, 0, 30)).Until(x => loadingdissapearedcondition) which im using to wait until Loading.. element is gone.
I also sometimes use this script :
private const string script = #"return ($('#{0}').jqGrid('getGridParam', 'reccount') !=x undefined) && ($('#{0}').jqGrid('getGridParam', 'reccount') != 0) && (!$('#load_{0}').is(':visible')) && (!$('#busyIcon').is(':visible'))";
private readonly string waitScript;
waitScript = string.Format(script, jqGridId);
public void WaitUntilLoadIconDissappears()
{
driver.WaitUntil(MAXWAIT, Wait);
}
public bool Wait()
{
var executeScript = ((IJavaScriptExecutor) driver).ExecuteScript(waitScript);
bool result;
bool tryParse = bool.TryParse(executeScript.SafeToString(), out result);
return tryParse && result;
}
to find if jqGrid has records and loading done.
I require something better - as even the above two does not make driver wait until load finishes, if we are using local data for jqGrid. Im also curious what is the best way, or at the minimum, how others are dealing with this problem.
I never used Selenium before, so I'm not sure that I understood your problem correctly. jqGrid will be first initialized and then (optionally) the data can be loaded from the server. During the initializing stage the original <table id="grid"></table> element will be converted to relatively complex HTML fragment which is the grid. At the end of the initialization the DOM element of the table (the $("#grid")[0]) will get the expando grid.
So you can use the test like
if ($("#grid")[0].grid) {
// grid is initialized
}
to determine that the grid is already initialized. jqGrid uses the same test internally (see here for example).
Here is solution for Java and jqgrid.
If grid data is not loaded yet then right pager has no value, so simply check its length. Methods such as isElementPresent, isDisplayed etc. seems not to work for grid right pager object. It's always present in page code while ajax, but text value is set when dynamic data is loaded.
public void waitForGridPagerRight(String gridName) throws Exception {
for (int second = 0;; second++) {
if (second >= 15) {
fail("Timeout.");
}
try {
if (driver
.findElement(By.id("pager_" + gridName + "_right"))
.getText().length() > 2)
break;
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
Not sure why #Oleg's answer didn't work for me. It seemed like grid was being populated even before the ajax call was being made. It appears there's some change in newer versions maybe. It look like the last thing to happen in the ajax call is that the "loading" block is hidden, so instead I find that element and check it's display attribute a la:
def wait_for_jqgrid(self, t=20):
def check_jqgrid(driver):
#the last thing jqgrid does after the ajax call is to turn off the loading div
#so we find it and check to see if its display attribute is no longer set to 'none'
script = 'pid = $.jgrid.jqID($(".ui-jqgrid-btable").get(0).p.id); return $("#load_"+pid).get(0).style.display == "none";'
return driver.execute_script(script)
WebDriverWait(self.driver, t).until(check_jqgrid)
When the loading div is hidden, we are done. This is python but the same javascript bit should work in Java or whatever.

Problem using Selenium to automate a postback link that is inside an ASP.NET UpdatePanel [duplicate]

This question already has answers here:
Selenium IDE click() timeout
(2 answers)
Closed 3 years ago.
I have a GridView control with sorting enabled inside an UpdatePanel. I used Selenium IDE to record a test that clicks on the sort link of the table, but when I try to execute the test it get's stuck on the click command. Looking at the log I see:
[info] Executing: |click | link=Name | |
[error] Timed out after 30000ms
I haven't tried it with Selenium-RC yet, I don't know if it will be any different. I don't want Selenium to wait for anything. Any ideas of how to work around it?
Thanks!
when using selenium + Ajax (or the page just get refresh under certain conditions).
I usually use:
selenium.WaitForCondition
or I created the following code recently (the page uses frames).
public bool AccessElementsOnDynamicPage(string frame, Predicate<SeleniumWrapper> condition)
{
DateTime currentTime = DateTime.Now;
DateTime timeOutTime = currentTime.AddMinutes(6);
while (currentTime < timeOutTime)
{
try
{
SelectSubFrame(frame);
if (condition(this))
return true;
}
catch (SeleniumException)
{
//TODO: log exception
}
finally
{
currentTime = DateTime.Now;
}
}
return false;
}
public bool WaitUntilIsElementPresent(string frame, string locator)
{
return AccessElementsOnDynamicPage(frame, delegate(SeleniumWrapper w)
{
return w.IsElementPresent(locator);
});
}
public bool WaitUntilIsTextPresent(string frame, string pattern)
{
return AccessElementsOnDynamicPage(frame, delegate(SeleniumWrapper w)
{
return w.IsTextPresent(pattern);
});
}
Soon you will get to the point you will need selenium RC integrated on your development environment, for this I recommend you to read:
How can I make my Selenium tests less brittle?
It is around waiting but for specific elements that should be (or appear) on the page.