I've got the same issue and googled a lot but found no workable solutions. The timeout solution is not applicable to my situation. At last it seems the only way that really works is to use a global hook.
For more information about hook, please refer to this excellent post: Global keyboard capture in C# application
So, in the hook handling code taken from above link, add something like this:
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode == 121) //F10 key
{
try
{
UnhookWindowsHookEx(_hookID);//avoid ESC key to be captured
SetForegroundWindow(_handle);
SendKeys.Send("{ESC}");
_hookID = SetHook(_proc);
}
catch (Exception ex)
{
}
}
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
related code below:
using System.Windows.Automation; //you need to reference UIAutomationClient and UIAutomationTypes
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
private IntPtr _handle;
//I forget where I got the code of the function below, probably also from stackoverflow. Thanks to the original author!
private IntPtr getIntPtrHandle(IWebDriver driver, int timeoutSeconds = 30)
{
var end = DateTime.Now.AddSeconds(timeoutSeconds);
while (DateTime.Now < end)
{
// Searching by AutomationElement is a bit faster (can filter by children only)
var ele = AutomationElement.RootElement;
foreach (AutomationElement child in ele.FindAll(TreeScope.Children, Condition.TrueCondition))
{
if (!child.Current.Name.Contains(driver.Title)) continue;
return new IntPtr(child.Current.NativeWindowHandle); ;
}
}
return IntPtr.Zero;
}
also put _handle = getIntPtrHandle(webdriver); somewhere BEFORE your webdriver.Navigate().GoToUrl() statement.
I tested the above. After excecuting GoToUrl, press F10 somewhere (sometimes twice) and the page stops loading.