C#, FierFox, Selenium v3.8
My purpose is movement cursor emulation in browser, using IMouse.MouseMove. Google searching gives me something like that, but I always receive System.NullReferenceException.How I should to use IMouse interface?
Simple console app:
FirefoxDriverService service = FirefoxDriverService.CreateDefaultService(Directory.GetCurrentDirectory() + "\\bin\\");
service.FirefoxBinaryPath = #"C:\Program Files (x86)\Mozilla Firefox\firefox.exe";
IWebDriver FF = new FirefoxDriver(service);
FF.Navigate().GoToUrl("https://www.google.ru/");
IWebElement element = FF.FindElement(By.Name("btnK"));
Actions act = new Actions(FF);
act.MoveToElement(element).Perform(); // It's OK
ILocatable hoverItem = (ILocatable)element;
IMouse mouse = ((IHasInputDevices)FF).Mouse;
mouse.MouseMove(hoverItem.Coordinates, 100, 100); // System.NullReferenceException
FF.Quit();
The short answer is that you don't do that in the .NET bindings. The IKeyboard and IMouse interfaces aren't intended to be used by users' code. This is despite the fact that they're public, and do have documentation. What you're running into is that those interfaces will not work for drivers that implement the W3C WebDriver specification. At the moment, that list is Firefox and IE (when using version 3.5 or later of the IE driver), but that list is going to grow to include Chrome and Edge soon, and eventually Safari too. The appropriate way to simulate mouse movement with the .NET bindings is through using the Actions class.
Related
I am writing automated tests using Selenium. I want to set the download directory in Edge so that I can download files as part of my test. There is an EdgeOptions object that I can provide when creating the EdgeDriver, but I don't know what to set on the EdgeOptions.
I know the equivalent of how to do this in Chrome
chromeOptions.AddUserProfilePreference("download.default_directory", #"C:\temp")
and Firefox
firefoxOptions.SetPreference("browser.download.dir", #"C:\temp")
But, how do I do the same thing in Edge? And get it to download automatically without a save prompt?
As #Prany already mentioned, probably there is no way to set download automatically. And if I right understood, you want to handle with native window dialogue, when you are clicking on download button. Selenium cannot interact with native windows, but you can use this framework. The sample code would be like this:
// Press the A Key Down
KeyboardSimulator.KeyDown(Keys.A);
// Let the A Key back up
KeyboardSimulator.KeyUp(Keys.A);
// Press A down, and let up (same as two above)
KeyboardSimulator.KeyPress(Keys.A);
// Simulate (Ctrl + C) shortcut, which is copy for most applications
KeyboardSimulator.SimulateStandardShortcut(StandardShortcut.Copy);
// This does the same as above
KeyboardSimulator.KeyDown(Keys.Control);
KeyboardSimulator.KeyPress(Keys.C);
KeyboardSimulator.KeyUp(Keys.Control);
So you can simulate Ctrl + V keyboard action and Enter action. Hope it helps.
You can do this for Edge like this:
// hide driver Console? true/false
EdgeDriverService service = EdgeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true; // hide Console
// change Standard-Download-Path
EdgeOptions options = new EdgeOptions();
var downloadDirectory = "C:\temp";
// Setting custom download directory
options.AddUserProfilePreference("download.default_directory", downloadDirectory);
// start Selenium Driver:
webdriver = new EdgeDriver(service, options);
// max. Window
webdriver.Manage().Window.Maximize();
The same method used in the test automation project I wrote in c # does not work in internet explorer 11 even though the movement method I use is chrome, firefox and edge. It does not give any errors, but the next action is fail
log.Debug("fare " + by + " üzeriine dogru haraket ediyor, webelement label ");
IWebElement element = GetElement(by);
Actions Actions = new Actions(Driver);
WaitElementToClickable(Driver, by, 5);
Actions.MoveToElement(element);
Actions.Perform();
WaitElementToClickable(Driver, by, 5);
I spent a long time trying to get actions to work across all browsers, and for IE I found the following helped.
Selenium webdriver v2.29.0 (https://github.com/SeleniumHQ/selenium/blob/master/java/CHANGELOG) added:
IEDriver supports "requireWindowFocus" desired capability. When
using this and native events, the IE driver will demand focus and
user interactions will use SendInput() for simulating user
interactions. Note that this will mean you MUST NOT use the
machine running IE for anything else as the tests are running.
When I set the IEDriver I use:
InternetExplorerOptions options = new InternetExplorerOptions();
options.requireWindowFocus();
webDriver = new InternetExplorerDriver(options);
And all my move to and click events work fine. I'm using IE11.125-11.309 and Selenium (java bindings) 3.7.1.
When I create an instance of the Firefox Web driver, it successfully opens Firefox. However, it opens it with two tabs (one "regular" Firefox tab and one IE tab; the IE tab is active and remains active for the duration of the testing unless I manually switch to the tab that the test is actually executing in).
It will run the test in the Firefox tab (i.e. the non-active one).
I'm instantiating my Firefox web driver like this:
var firefoxOptions = new FirefoxOptions()
{
Profile = new FirefoxProfile(),
UseLegacyImplementation = false,
BrowserExecutableLocation = #"C:\Program Files (x86)\Mozilla Firefox\Firefox.exe"
};
firefoxDriver = new FirefoxDriver(firefoxOptions);
firefoxDriver.Manage().Timeouts().ImplicitWait = new TimeSpan(0, 0, 10);
I'd include the code for the unit test, too, but the problem occurs during initialization prior to me running any tests.
Also, when I do cleanup like this:
[TestCleanup]
public void Cleanup()
{
if (firefoxDriver != null)
{
firefoxDriver.Close();
firefoxDriver.Dispose();
}
}
it closes the tab that the test was running in (the Firefox tab). However, it only closes that tab - the IE tab and the browser both stay open.
This question seems to be somewhat related, but the behavior's somewhat different because Selenium isn't trying to actually execute the test in both tabs - it only ever uses the one tab. Also, the OP there was using Firefox 20.0 and I'm using Firefox 52.2.0.
Simply, we can create profile and use it. I answered here Firefox 44.0.1 opening two tabs , when running selenium webdriver code
Another way, we can create profile pro-grammatically like
FirefoxProfile profile= new FirefoxProfile();
profile.setPreference(“browser.startup.homepage”,”https://...");
WebDriver driver = new FirefoxDriver(profile);
Just use about:config in firefox URL , it will provide settings.
I have the following program:
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Edge;
namespace ConsoleApplication1
{
static class Program
{
static void Main()
{
//var driver = new ChromeDriver();
var driver = new EdgeDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(20));
driver.Navigate().GoToUrl("http://www.cornelsen.de/shop/registrieren-lehrer");
driver.FindElement(By.Id("email")).SendKeys("dummy#user.de");
}
}
}
When I run this in Chrome or any other browser aside from Edge, then the email adress is entered correctly. But if I try the same thing in Edge, the "#" character is missing. The field displays only "dummyuser.de".
Any idea what I can do?
As a workaround, you can set the input value directly via ExecuteScript():
IWebElement email = driver.FindElement(By.Id("email"));
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string script = "arguments[0].setAttribute('value', 'arguments[1]');";
js.ExecuteScript(script, email, "dummy#user.de");
Or, what you can do is to create a fake input element with a predefined value equal to the email address. Select the text in this input, copy and paste into the target input.
Not pretty, but should only serve as a workaround:
// create element
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string script = #"
var el = document.createElement('input');
el.type = 'text';
el.value = 'arguments[0]';
el.id = 'mycustominput';
document.body.appendChild(el);
";
js.ExecuteScript(script, "dummy#user.de");
// locate the input, select and copy
IWebElement myCustomInput = driver.FindElement(By.Id("mycustominput"));
el.SendKeys(Keys.Control + "a"); // select
el.SendKeys(Keys.Control + "c"); // copy
// locate the target input and paste
IWebElement email = driver.FindElement(By.Id("email"));
email.SendKeys(Keys.Control + "v"); // paste
It wasn't as easy as I thought after all. Issues with alecxe's answer:
arguments[0].setAttribute('value', '...'); works only the first time you call it. After calling element.Clear();, it doesn't work any more. Workaround: arguments[0].value='...';
The site doesn't react on the JavaScript call like it would on element.SendKeys();, e.g. change event is not invoked. Workaround: Send the first part of the string up to the last "forbidden" character via JavaScript, the rest via WebElement.SendKeys (in this particular order, bc if you do another JavaScript call to the same field after SendKeys(), there will occur no change event either).
I also realized that there are more "forbidden" characters in Edge, e.g. accented or Eastern European ones (I'm Central European). The problem with 2. is that the last character might be a forbidden character. In this case, I append a whitespace. Which of course affects the test case behavior, but I haven't had any other idea.
Full C# code:
public static void SendKeys(this IWebElement element, TestTarget target, string text)
{
if (target.IsEdge)
{
int index = text.LastIndexOfAny(new[] { '#', 'Ł', 'ó', 'ź' }) + 1;
if (index > 0)
{
((IJavaScriptExecutor) target.Driver).ExecuteScript(
"arguments[0].value='" + text.Substring(0, index) + "';", element);
text = index == text.Length ? Keys.Space : text.Substring(index);
}
}
element.SendKeys(text);
}
This problem used to occur in old browsers. Apparently it returned in Edge.
You can try sending the string in pieces
IWebElement email = driver.FindElement(By.Id("email"));
email.SendKeys("dummy");
email.SendKeys("#");
email.SendKeys("user.de");
Or try using # ASCII code
driver.FindElement(By.Id("email")).SendKeys("dummy" + (char)64 + "user.de");
Try to clear the Text field first.
try following
driver.FindElement(By.Id("email")).clear().SendKeys("dummy#user.de");
Have you tried Copy Paste?
Clipboard.SetText("dummy#user.de");
email.SendKeys(OpenQA.Selenium.Keys.Control + "v");
Hope it could help.
I just added one extra line to click on text field and then send keys, I tried this and its working for me.
Code is written in java, you can change that to any other, if you want.
//INITIALISE DRIVER
WebDriver driver = null;
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.navigate().to("http://www.cornelsen.de/shop/registrieren-lehrer");
driver.manage().window().maximize();
//CLICK EMAIL FIELD, JUST TO HAVE FOCUS ON TEXT FIELD
driver.findElement(By.id("email")).click();
driver.findElement(By.id("email")).sendKeys("dummy#user.de");
I'm the Program Manager for WebDriver at Microsoft. I just tried to reproduce your issue on my home machine (Windows 10 build 10586) and couldn't reproduce. Your exact test entered the '#' symbol fine.
You should check if you have the latest version of Windows 10 and WebDriver. If you hit the Windows key and type "winver" and hit enter it'll open a popup with the Windows version info. You want it to say
Microsoft Windows
Version 1511 (OS Build 10586.104)
This is the latest version of Windows 10 released to the public. If you have this version you'll also need the corresponding version of WebDriver found here:
http://www.microsoft.com/en-us/download/details.aspx?id=49962
Note that if the build is 10240 that you're on the original release build. Our November update added substantial support for new features (like finding elements by XPath and more!) along with bug fixes which might explain your issues.
Lastly I should note we have an Insiders release as well for WebDriver to match with the Insiders program. If you're subscribed to the Insiders program and want to see the newer features and bug fixes for WebDriver you can find the download here:
https://www.microsoft.com/en-us/download/details.aspx?id=48740
Note that it currently supports build 10547 which was actually before the November update. It'll be updated very shortly (next couple of days) to support the latest Windows Insiders flight, build 14267.
Sorry but I not agree with the last comment (Program Manager for WebDriver at Microsoft). I can reproduce the problem. This is my configuration:
Target Machine (Hub node where tests are run):
Win 10 build 10585.104
MS Edge 25.10586.0.0
MS EdgeHTML 13.10586
Selenium framework:
SeleniumHQ (for Java): 2.48.0
I am using Selenium Grid to run my suite. In this case, I was only doing conceptual test of Egde implementing a basic test:
1. Start Hub in local machine (Win 7) opening console (administrator privileges)
2. Register Node in Hub in target remote machine (Win 10 build 10585) opening console (in this case without administrator privileges because in other way edge hangs when create new session).
Setting up my grid and checking that everything is ok when I try to write my account name in login page I can not see the # and my basic test fails (wrong credentials).
I have introduced # by hand in the moment edge is opened (interrupt point) and I can see symbol.
I have sent "###############" to the text field and I can not see any. In summary, I have tried many things and I can not see #
When I started with Web Automation Testing using Selenium (Java) I remember this behaviour in old versions of Firefox and Chrome. I not really sure which one but it was reproducible in old version.
This partial basic code (implementated with pageobject) IS WORKING with Firefox 35.0 and Chrome 48.0.2564.109 but NOT IS WORKING with Edge's version I put at the beginning of my comment.
WebElement element = WebDriverExtensions.findElement(context, By.cssSelector("input[name='username'][type='email']"));
element.clear();
element.sendKeys(email);
Front Developers are using AngularJS and are validating user's text input to match with a welformatted email:
I afraid that current Edge version does not support sendkeys with this kind of character, maybe the problem is front on-line validation and Edge has to suits these situations because they are really common.
Best regards
None of the above worked for me with the version 2.52. This worked for me :
EdgeDriver edgeDriver = new EdgeDriver("folder of my edge driver containing MicrosoftWebDriver.exe");
IJavaScriptExecutor js = _edgeDriver as IJavaScriptExecutor;
js.ExecuteScript("document.getElementById('Email').value = 'some#email.com'");
Make sure to replace the ".getElementById('Email')" with what you should use to find your field with javascript and replace the "folder of my edge driver containing MicrosoftWebDriver.exe" with the correct path.
Good luck!
I attempting to send a Ctrl + 0 to set IE 9 to 100%.
I have tried the following snippets of code:
IWebElement query = Driver.FindElement(By.TagName("html"));
query.SendKeys("^0");
query.SendKeys(Keys.Control + Keys.NumberPad0);
I have also tried the actions object code:
Actions action = new Actions(Driver);
action.KeyDown(Keys.Control).SendKeys("0").KeyUp(Keys.Control).Perform();
I have read that in Java, WebDriver supports Keys.chord()
But I cannot find an implementation of this in C#.
Any ideas would be helpful.
The <html> tag will never be "visible" to the driver, thus can't have keys sent to it. The following code works for me:
IWebElement element = driver.FindElement(By.TagName("body"));
element.SendKeys(Keys.Control + "0");
However, with the most recent versions of the IEDriverServer.exe, you will not be able to get this far unless you set a special option for the driver to disable detection of the zoom setting. If your zoom level is not set to 100%, the InternetExplorerDriver constructor will throw an exception unless you instantiate your driver with something like:
InternetExplorerOptions options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
IWebDriver driver = new InternetExplorerDriver(options);