Selenium Script halts while switching window handles - c#

Im facing exactly the same issue as described here
but its a closed thread.
Im using selenium webdriver 2.48.2, on win7 IE 11.
The situation goes like this, I have a test that clicks on a button which is supposed to open a new experiment, this new experiment opens in new tab on chrome and in the same tab on firefox, but opens in new window on IE11 when it is run through selenium. But strange thing is that it does not open in new window when the browser was opened manually instead of through selenium script.
maybe the selenium script opens new webdriver? and script halts while searching for new page's elements. what the code does is, it checks if the new handle was opened or not, finds the new handle and then switches the window handle to newer one.
Here is the c# code snippet.
private static TResult TriggerAndWaitForNewWindow<TResult>(PageObject pageObject, Action action, int timeout = 30)
where TResult : PageObject, new()
{
IParent parent = pageObject.Driver;
List<String> existingHandles = pageObject.Driver.WindowHandles.ToList();
action();
string popupHandle = Wait.Until(() =>
{
string foundHandle = null;
List<string> currentHandles = pageObject.Driver.WindowHandles.ToList();
var differentHandles = GetDifference(existingHandles, currentHandles);
if (differentHandles.Count > 0)
{
Boolean hasSomeLength = differentHandles[differentHandles.Count-1].Length > 1;
if (hasSomeLength)
foundHandle = differentHandles[differentHandles.Count - 1];
}
return foundHandle;
}, "Waiting for new Window Handle to appear", timeout, 2000);
// Init the new page object but override the window handle
TResult page = PageObject.Init<TResult>(parent);
page.WindowHandle = popupHandle;
page.SwitchToMyWindow();
return page;
}
private static List<String> GetDifference(List<string> existingHandles, List<string> currentHandles)
{
System.Threading.Thread.Sleep(15000);
return currentHandles.Except(existingHandles).ToList();
}
Halts inside this function on IE11
public Boolean SwitchToMyWindow()
{
try
{
String windowHandle = this.WindowHandle; // must be the old handle
try
{
if (this.Driver.CurrentWindowHandle == windowHandle)
{
Log.Info("No need to cswitch window");
return true;
}
}
catch(Exception e)
{
Log.Warn("We have no current driver window, must have been closed");
}
Log.Info("Switching to Window Handle {0}", this.Driver.CurrentWindowHandle);
this.Driver.SwitchTo().Window(windowHandle); <---- Halts here on IE11
//Pause.milliSeconds(500);
Boolean switched = Wait.Until(() =>
this.Driver.CurrentWindowHandle == windowHandle, "Waiting for my window handle to be the active one", 5, 1000);
}
catch (OpenQA.Selenium.WebDriverTimeoutException tEx)
{
}
return true;
}
Did anyone else ever faced this issue? How can resolve it?

Can you verify if Selenium supports your target OS?
It is possible that Selenium is not fully supported on your Target OS.
Please check the following link for more details.
http://grokbase.com/t/gg/webdriver/1267fdkgaa/openqa-selenium-nosuchwindowexception-with-ie9-and-windows-2008

Related

C# Selenium keeps creating chrome instances

My question is, how to prevent Selenium from creating multiple chrome instances?
Details:
Using Selenium and chromedriver I created an automation testing program. Strangely, although most runs are as expected, about one out of twenty would create many chrome console (black, empty) windows, with one actual browser window. The browser window would finish the work but not disposed correctly, and no exceptions were thrown. Once I manually closed the only browser window, all other windows were closed too.
This time I caught it in visual studio debug mode, I found even my program paused at a breakpoint, the chrome console windows were still being spawned. In the task manager there were 17 chrome.exe sessions, and no chrome was created before my program started.
Out of all the console windows, only one (the leftmost one on screen, maybe the first one that was created) had some information and all others were blank:
[2400:1204:0412/171721.457:ERROR:gl_surface_egl.cc(808)] EGL Driver
message (Error) eglCreateContext: Requested GLES version (3.0) is
greater than max supported (2, 0).
[2400:1204:0412/171721.578:ERROR:gl_context_egl.cc(352)]
eglCreateContext failed with error EGL_SUCCESS
Then after the only browser window finished routine work, another spawned console window contained some additional information:
[8016:13204:0412/172631.461:ERROR:cache_util_win.cc(20)] Unable to
move the cache: Access is denied. (0x5)
[8016:13204:0412/172631.462:ERROR:cache_util.cc(146)] Unable to move
cache folder
C:\Users\cal\AppData\Local\Temp\scoped_dir2496_2059150988\Default\Cache\Cache_Data
to
C:\Users\cal\AppData\Local\Temp\scoped_dir2496_2059150988\Default\Cache\old_Cache_Data_000
[8016:13204:0412/172631.463:ERROR:disk_cache.cc(186)] Unable to create
cache
Below is my c# code for creating chrome browser:
public static ChromeDriver GetChromeBrowser(bool bHeadless = false, string sProxy = "", string chromeProfileDir = "")
{
var chromeoptions = GetChromeOptions(bHeadless, chromeProfileDir);
var chromeDriverService = ChromeDriverService.CreateDefaultService(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
// hide prompt window
chromeDriverService.HideCommandPromptWindow = true;
ChromeDriver browser = null;
int nCount = 0;
while (browser == null && nCount < 3)
{
try
{
browser = new ChromeDriver(chromeDriverService, chromeoptions, TimeSpan.FromSeconds(180));
}
catch (Exception ex)
{
// try a different port:
chromeoptions = GetChromeOptions(bHeadless, chromeProfileDir);
}
nCount++;
}
return browser;
}
private static ChromeOptions GetChromeOptions(bool bHeadless = false, string chromeProfileDir = "")
{
var chromeoptions = new ChromeOptions();
if (!string.IsNullOrEmpty(chromeProfileDir))
{
string sProfileFullPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), chromeProfileDir);
if (!Directory.Exists(sProfileFullPath))
{
try
{
Directory.CreateDirectory(sProfileFullPath);
}
catch (Exception)
{
}
}
chromeoptions.AddArguments("--profile-directory=" + sProfileFullPath);
}
chromeoptions.AddArguments("--disable-notifications");
chromeoptions.AddArguments("--no-sandbox");
chromeoptions.AddArguments("--disable-dev-shm-usage");
chromeoptions.UnhandledPromptBehavior = UnhandledPromptBehavior.Dismiss;
int nPortNumber = GetARandomPortNumber();
chromeoptions.AddArguments($"--remote-debugging-port={nPortNumber.ToString()}");
if (bHeadless)
{
chromeoptions.AddArguments("--headless");
chromeoptions.AddArguments("--disable-gpu");
// do not load images:
chromeoptions.AddArguments("--blink-settings=imagesEnabled=false");
}
return chromeoptions;
}
I have also made a screenshot to show how it look like. As you can see, many blank chrome windows were created.
The problem is highly intermittent and hard to reproduce. I don't know if it is enough to pinpoint the problem. Any suggestion is appreciated.

C# - Process with an id of "xxxxxx" is not running

I have a windows form and I make the following call to open chrome up with a URL:
string uri = Uri.EscapeUriString(URL.ToString());
Process process = Process.Start("chrome", uri + " --new-window");
return process.Id;
The problem is that I get the error: "Process with an id of "xxxxxxx" is not running" when I call the following:
procsChrome = Process.GetProcessById(processID);
The processID is the one returned in the previous code snippet. Now, this WORKS when I have NO CHROME WINDOW OPEN.
But if I have another chrome window open, I get this error. I monitored the processes in Task Manager and when no chrome is open, a new process with the the process id returned from the code snippet 1 is created.
When one or more chrome windows are already open, I get a process id from code snippet 1, but the newly opened chrome window is running under some other id. Why is this happening?
Edit 2:
Here is the method I get the error on. The parameter int processID is the process.Id returned above from code snippet 1.
public static string GetCodeFromURL(int processID)
{
Process procsChrome = null;
try
{
if (processID == -1)
{
Console.WriteLine("-1 returned as ID");
return null;
}
procsChrome = Process.GetProcessById(processID); //I GET ERROR HERE
// the chrome process must have a window
if (procsChrome.MainWindowHandle == IntPtr.Zero)
MessageBox.Show("Process failed");
// to find the tabs we first need to locate something reliable - the 'New Tab' button
AutomationElement root = AutomationElement.FromHandle(procsChrome.MainWindowHandle);
var SearchBar = root.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
if (SearchBar != null)
{
bool noCode = false;
while (noCode == false)
{
string fullURL = (string)SearchBar.GetCurrentPropertyValue(ValuePatternIdentifiers.ValueProperty);
if (!(fullURL.Contains("code") && fullURL.Contains("state")))
{
if (procsChrome.HasExited)
{
Console.WriteLine("Process failed. User closed browser.");
procsChrome.Close();
noCode = true;
}
}
else
{
string stateToken = HttpUtility.ParseQueryString(fullURL.Substring(new[] { 0, fullURL.IndexOf('?') }.Max())).Get("state");
if (stateToken.Equals("296bc9a0-a2a2-4a57-be1a-d0e2fd9bb601"))
{
noCode = true;
string code = HttpUtility.ParseQueryString(fullURL.Substring(new[] { 0, fullURL.IndexOf('?') }.Max())).Get("code");
procsChrome.CloseMainWindow();
procsChrome.Close();
return code;
}
}
}
}
}
catch (Exception exception)
{
Console.WriteLine("An exception occured on getting the URL. Please try again. The exception is: " + exception.ToString());
return null;
}
return null;
}
Thanks.
Chrome seems to behave in this way by default, creating anothing process and closing the original one, which means you end up with an incorrect Process ID. And when you have multiple Chrome processes with the same website/title you end up having no control over it.
As some suggested using the parameter "--incognito" will solve it, whoever this would also create other unwanted behavioural issues.
I've looked at the Chrome parameters list and tried a few, using the parameter "--no-service-autorun" seems to have solved the issue.
Not sure why chrome is behaving like that. Can you try to have your code launch chrome in incognito mode?
Using the test code below i was able to launch 2 distinct incognito processes each with their own process id. Note: these launched in the same browser window as 2 tabs.
I think using --incognito will get you out of trouble.
public class LaunchChromeProof
{
private readonly ITestOutputHelper _output;
public LaunchChromeProof(ITestOutputHelper output)
{
_output = output;
}
[Fact]
public void CanLaunchChromeIcognito_AndFetchProcesses_ByID()
{
var chromePath = #"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe";
var chromeProcess = Process.Start(chromePath, "www.google.com --incognito");
Assert.NotEqual(0, chromeProcess.Id);
//launch a second session
var chrome2ndProcess = Process.Start(chromePath, "www.google.com --incognito");
Assert.NotEqual(0, chrome2ndProcess.Id);
_output.WriteLine($"Session 1 ProcessID: {chromeProcess.Id}");
_output.WriteLine($"Session 2 ProcessID: {chrome2ndProcess.Id}");
//check we can fetch the correct process by the process id for each session
var fetchProcess1 = Process.GetProcessById(chromeProcess.Id);
Assert.Equal(chromeProcess.Id, fetchProcess1.Id);
var fetchProcess2 = Process.GetProcessById(chrome2ndProcess.Id);
Assert.Equal(chrome2ndProcess.Id, fetchProcess2.Id);
_output.WriteLine($"Fetched Session 1 Process: {fetchProcess1.Id}");
_output.WriteLine($"Fetched Session 2 Process: {fetchProcess2.Id}");
}

Ranorex can not start Chrome browser, no warning or error

Ranorex 7.0.1, evaluation version, 28 days left
OS, Windows 10
Chrome driver, 2.29
Selenium webdriver standalone server, 3.4.0
I have set up Endpoint as Local Selenium WebDriver, its connection has been tested as "Connected".
WebDriver, WebDriver.Support have been added to References.
The code snippet is shown below:
namespace HoT
{
class Program
{
[STAThread]
public static int Main(string[] args)
{
// Uncomment the following 2 lines if you want to automate Windows apps
// by starting the test executable directly
//if (Util.IsRestartRequiredForWinAppAccess)
// return Util.RestartWithUiAccess();
Keyboard.AbortKey = System.Windows.Forms.Keys.Pause;
int error = 0;
var webDriver = new ChromeDriver(#"C:\Users\myName\Documents\Ranorex\RanorexStudio Projects\HoT\HoT\ExternalModules\chromedriver");
webDriver.Navigate().GoToUrl("http://www.google.com");
try
{
error = TestSuiteRunner.Run(typeof(Program), Environment.CommandLine);
}
catch (Exception e)
{
Report.Error("Unexpected exception occurred: " + e.ToString());
error = -1;
}
return error;
}
}
}
All I got is a console window and a pop up window, there is no Chrome browser instance or warning or error. Anyone knows why?
You need to start the browser with
Host.Current.OpenBrowser("http://www.google.com", "Chrome", "", false, false, false, false, false);

C# Timeout with Solidworks VBA Macro

I have a few functions in a Solidworks Addin which call on a VBA macro (Via the runMacro2 method) a co-worker has been working on for the last few weeks. In his code he calls a Solidworks function which, under certain, unknown conditions, hangs for a long period of time. How long seems to depend upon the size and quantity of bodies in the part. Considering at least one of the functions we want to run this from i automatic, this just wont do.
I have tried using the Thread.Join(int) method (shown below) but it doesnt work. I also tried modifying the code from this answer Close a MessageBox after several seconds with the same results. Is there anything I can do either in C# or VBA to handle a timeout for this without re-writing his entire macro?
public void runBB()
{
Stopwatch testStop = new Stopwatch();
Thread workerThread = new Thread(bbRun);
testStop.Start();
workerThread.Start();
if (!workerThread.Join(50))
{
workerThread.Abort();
testStop.Stop();
MessageBox.Show("Unable to generate Bounding Box after " + testStop.ElapsedMilliseconds/1000 + " seconds. Please enter data manually.", "Solidworks Derped Error.");
}
return;
}//Still uses Macro (2-5-16)
public static void bbRun()
{
iSwApp.RunMacro2(macroPath + "BOUNDING_BOX.swp", "test11", "main", 0, out runMacroError);
return;
}
I was getting this same exact issue with SOLIDWORKS hanging on an open of a file. Almost all reference on SO was that you should never do this, but in this scenario, you either have to close it or wait forever. In C# I created a callWithTimeout method:
private void callWithTimeout(Action action, int timeoutMilliseconds, String errorText) {
Thread threadToKill = null;
Action wrappedAction = () =>
{
threadToKill = Thread.CurrentThread;
action();
};
IAsyncResult result = wrappedAction.BeginInvoke(null, null);
if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds)) {
wrappedAction.EndInvoke(result);
} else {
threadToKill.Abort();
throw new TimeoutException(errorText);
}
}
Then the code that was hanging put in a block as such:
bool timedOut = false;
try {
callWithTimeout(delegate() {
// code that hangs here
}, 60000, "Operation timed out. SOLIDWORKS could not open the file. This file will be processed later.");
} catch (TimeoutException){
timedOut = true;
} finally {
if(timedOut) {
Process[] prs = Process.GetProcesses();
foreach (Process p in prs) {
if (p?.ProcessName.Equals("SLDWORKS") ?? false)
p?.Kill();
}
}
}

selenium rc + c# how to handle the timed out problem after runned a new browse?

all
When I learned the selenium rc how to use selenium.click to open a new browse, I have met a problem. The new browse can be opened correctly, but the test tool NUint showed "timed out" problem, whatever I added the time, it always has the timed out problem.The whole codes as following:
[Test]
public void SelectTest()
{
//selenium = new DefaultSelenium("localhost", 4444, "*chrome","http://www.webkey.cn/demo/docs/index2.asp?url=/demo/docs/menuselect/");
// selenium.Start();
selenium.Open("http://www.webkey.cn/demo/docs/index2.asp?url=/demo/docs/menuselect/");
selenium.WaitForPageToLoad("8000");
selenium.SelectWindow("name=main");
selenium.Select("city","label=上海市");
Assert.AreEqual("上海市",selenium.GetSelectedLabel("city"));
selenium.Select("country","index=1");
Assert.AreEqual("徐汇区",selenium.GetSelectedLabel("country"));
selenium.SelectFrame("relative=up");
selenium.SelectFrame("Header1");
selenium.Click("link=首页");
selenium.WaitForPageToLoad("10000");// This code has timed out problem.
}
First increase default selenium timeout(as i remeber defaulttimeout = 30000):
selenium.SetTimeout("90000"); // 1.5 minute
And second increase wait time for page load:
selenium.WaitForPageToLoad("10000"); // it's only 10 seconds,
//increase to 60000 - one minute
EDIT:
At that i've tested all clicks done by ajax and i use followoning methiod in order to wait some element on page after redirect, so try to use this for wait redirect:
public static bool WaitForElement(String waitingElement, DefaultSelenium selenium)
{
var isElementExists = selenium.IsElementPresent(waitingElement);
if (!isElementExists)
{
Thread.Sleep(50);
return WaitForElement(waitingElement, selenium);
}
else
{
return isElementExists;
}
}
Example:
selenium.Open("/sign-up");
WaitForElement("//input[#name='Invite']", selenium);//Wait...
Try
selenium.clickAndWait("link=首页");<br>
selenium.WaitForPageToLoad("60000");

Categories