I'm going to explain this the best I can.
I run tests using the 3 major browsers, firefox, chrome and IE.
I have line where I select data from a drop down menu. Here is an example of what I use.
new SelectElement(CPC_Main.driver.FindElement(By.XPath("//select[#id='orgVdc']"))).SelectByText("Selenium_vDC");
This will select my element orgVdc and select the text value by Selenium_vDC. This will work perfectly for Firefox however it hangs and timesout for Chrome.
From what I can tell the issue is related to the default value of that element.
For example if default value of the element is "Test_vDC" selenium will successfully change it "Selenum_vDC" for all browsers.
However if the default value was "Selenium_vDC" already then Chrome will hang on trying to select that same value.
I hope that explains this enough, in a nut shell Chrome does not like matching default values.
I had encountered issue like this in the past. I used to get exceptions like "The element is no longer attached to the DOM". The issues(stale reference exceptions) like these needs a solid exception handling to make sure Automation execution is not affected.
You can try the below code. You can modify the below code as per your code set up.
public void SetDropDownValue(string Xpath, string value)
{
var element = FindElement(By.Xpath("Xpath"));
var selectElement = new SelectElement(element);
//check whether the option is selectable or not
var wait = new WebDriverWait(this.driver, this.testCaseConfiguration.WaitTime);
wait.Until(ExpectedConditions.TextToBePresentInElement(selectElement , option));
try
{
selectElement.SelectByText(value);
}
catch (StaleElementReferenceException)
{
element = FindElement(By.Xpath("Xpath"));
selectElement = new SelectElement(element);
selectElement.SelectByText(value);
}
}
Related
Test below fails, saying that xpath expression is not correct. I did it according to online tutorials.
// open browser
IWebDriver webDriver = new FirefoxDriver();
// navigate to site
webDriver.Navigate().GoToUrl("https://localhost:44311/");
// identify details button
IWebElement detailsLink = webDriver.FindElement(By.XPath("//*[contains(., 'Details')]"));
// operation
detailsLink.Click();
var detailsLabel = webDriver.FindElement(By.XPath("//div[text() = 'Change in $'"));
// assertion
Assert.That(detailsLabel.Displayed);
I want to create simple Selenium test.
I'm pressing specific button to open new page
Checking if specific object is loaded correctly on that page
Button is <a></a> with Details inside. There are actually duplicates of that, the only unique thing is href. This might be the first issue, but I don't know how to "catch" it.
detailsLabel is actually a <div>Change in $</div> with class that I think is irrelevant to the tests.
So, my question is, how to write this test correctly? Test itself should be more or less fine, but detailsLink and detailsLabel has certain issues.
Edit
IWebElement detailsLink = webDriver.FindElement(By.CssSelector("[href*='Details?cryptocurrency=BTC']"));
//operation
detailsLink.Click();
var detailsLabel = webDriver.FindElement(By.XPath("//div[contains(text(),'Change in $')]"));
Return exception Selenium.StaleElementReferenceException for detailsLink
Edit
IWebElement detailsLink = webDriver.FindElement(By.CssSelector("[href*='Details?cryptocurrency=BTC']"));
detailsLink.Click();
var detailsLabel = webDriver.FindElement(By.XPath("//*[text()='Change in $```
Test fails at `detailsLabel`, fails to find our target `div`.
To validate if //*[contains(., 'Details')] xpath is unique you can do something like
List<WebElement>list = webDriver.FindElements(By.XPath("//*[contains(., 'Details')]"));
now, if list is empty - this means your locator is wrong and if it contains more than 1 element your locator is not unique.
But the better way is to validate this manually and directly on the webpage with F12 Inspector tool on your browser.
To locate the element containing some href without the specific href text use //href in case href is an element tag. Otherwise use //*[#href] if href is an attribute.
For the detailsLabel try using //div[contains(text(),'Change in')] xpath
I used Java syntax, but it's similar enough to C#
I'm working on a Product automation(Web CMS), where element.Click() shows the inconsistent behaviour. Basically we are using,
Selenium + Nunit GUI(unit testing framework) - To run the test cases from local on a particular environment
Selenium + Asp.net web application - Multiple user's can run the test cases on different environment
Here environment I mean different levels(Dev, SIT, QA, Production).
My Concern
In one of my test cases, I want to Click a button. So for that, I have tried few code. But all are inconsistent behaviour. Here Inconsistent I mean, the code whatever I wrote for clicking a button are only working in my local or server and viceversa.
1st attempt:-
I tried all the element locator's
IWebElement element = driver.FindElement(By.Id("element id goes here"))
Working fine at my local, but not in server
Result - Failed
2nd attempt:-
driver.FindElement(By.XPath("Element XPath goes here")).SendKeys(Keys.Enter);
Working fine at server, but not in local
Result - Failed
3rd attempt:-
IWebElement element = driver.findElement(By.id("something"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].click()", element);
Not working in both(local and server)
Result - Failed
At last, I tried waiting for the element to be visible and performing action
4th attempt:-
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
return wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("element xpath goes here")));
After webdriver wait performing action on that element (element.click())
Working fine at local but not in server
Result - Failed
I'm looking for a solution, where Clicking the button should not be an inconsistent behaviour. Basically it should work fine in both (Local and Server). Your help would be greatly appreciated..Thanks in advance
FYI - I'm testing in Mozilla Firefox browser 38.5.2
I'm using Selenium in C# locally on Win7 and remotely on Win10 and MacOS with the Firefox browser and also noticed that Firefox sometimes requires special treatment for IWebElement.Click(). So I wrote myself an extension method, which works fine for me, no matter by what locator the element was found:
public static void Click(this IWebElement element, TestTarget target)
{
if (target.IsFirefox)
{
var actions = new Actions(target.Driver);
actions.MoveToElement(element);
// special workaround for the FirefoxDriver
// otherwise sometimes Exception: "Cannot press more then one button or an already pressed button"
target.Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.Zero);
// temporarily disable implicit wait
actions.Release().Build().Perform();
target.Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(MyDefaultTimeoutInSeconds));
Thread.Sleep(500);
actions.MoveToElement(element);
actions.Click().Build().Perform();
}
else
{
element.Click();
}
}
If you want more stable behavior for your test cases, I would recommend using ChromeDriver. It never needs any special treatment at all, and it's also much faster than the FirefoxDriver.
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!
Setup Details:
Webdriver 2.39
IEDriverServer 2.39
I'm running Selenium automation on an internal site. The code works fine on Firefox 27 but there's an issue on IE8
I'm trying to first clear and enter text in a text field on IE. This fails on IE with the error "Element must not be hidden, disabled or read-only." I checked the element properties on IE and it does indeed show enabled as False, even though the element is plainly available. On Firefox, enabled is correctly set to True.
I've tried to use Xpath and sendkeys but they don't work. Here what I tried:
driver.FindElement(By.XPath("//input[#name='tagName']")).Clear(); - not working
driver.FindElement(By.XPath("//input[#name='tagName']")).SendKeys(tagName); - not working
driver.FindElement(By.Id("tagName")).SendKeys(Keys.Control); - not working
driver.FindElement(By.Id("tagName")).Clear(); - not working
driver.FindElement(By.Id("tagName")).SendKeys(tagName); - not working
Is there some way I can access this element on IE?
Thanks,
J.
We frequently test against IE8 and encounter "unique" Selenium issues.
Sometimes we use ExecuteScript to bypass Selenium's finicky selectors, and use jQuery to return the element or to manipulate it directly:
// Get an element
IWebElement element = (IWebElement) driver.ExecuteScript("return $('#tagName')[0]");
// Clear the value of a field
driver.ExecuteScript("$('input[name=\'tagName\']').val('');");
The best solution was the builder object of Selenium. I used this to force the automation to select the textbox and enter test like so:
IWebElement searchField = Global.driver.FindElement(by);
builder.Click(searchField).SendKeys(searchField, textToEnter).Perform();
This worked!
J.
WebElement searchField = Global.driver.FindElement(by);
builder.Click(searchField).SendKeys(searchField, textToEnter).Perform();
****its working but sending wrong text to the field.
For ex: i have to send "11-12-2015" and it is sending "28-12-2015".
Any Clue what's happening when performing inserting action.****
I am writing integration tests in c# and when I use the click() method on certain elements inside a dialog box nothing happens and I get no errors. It will click some of the elements inside the dialog but not others. I thought if it wasn't selecting them properly then it would throw and exception but it runs smooth and says test passed even though it never actually clicked the button. The dialog box is an iframe.
I thought maybe it was trying to click a button that wasn't display yet or enabled so I added this before the click() call:
_driver.SwitchTo().Frame(_frameElement);
_wait.Until(d =>
{
var shippingInfoButton = d.FindElement(By.CssSelector("input[title ='Info']"));
return shippingInfoButton.Displayed && shippingInfoButton.Enabled;
});
var infoButton = _driver.FindElement(By.CssSelector("input[title ='Info']"));
ScrollToElement(infoButton);
infoButton.Click();
again this runs with no thrown exceptions so I'm assuming it has found the element and it is both displayed and enabled.
Let me know if you need any more info. Thanks
I can't explain why the selenium driver .click() method won't fire on some elements in the page but not others, but I did find a solution.
Using IJavaScriptExecutor you can click the element using javascript instead and in my case it worked.
Here is the code to run the IJavaScriptExecutor and below is my whole method.
//IJavaScriptExecutor
IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
js.ExecuteScript("arguments[0].click();", infoButton);
//my whole method for clicking the button and returning the page object
public ShippingMethodDetailsPageObject SelectShippingMethodInfo()
{
_driver.SwitchTo().Frame(_frameElement);
_wait.Until(d =>
{
var shippingInfoButton = d.FindElement(By.CssSelector("input[title='Info']"));
return shippingInfoButton.Displayed && shippingInfoButton.Enabled;
});
var infoButton = _driver.FindElement(By.CssSelector("input[title ='Info']"));
IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
js.ExecuteScript("arguments[0].click();", infoButton);
_driver.SwitchTo().DefaultContent();
return new ShippingMethodDetailsPageObject(_driver, false);
}
I ran into a similar problem. If it's the same problem there's a fault in the ChromeDriver it can't click certain elements because of surrounding divs etc. Bit lame really.
A simple fix is to send the Enter key e.g. element.SendKeys(Keys.Enter). Seems to work across all browsers.
I have some tests that works in Firefox all the times, and in Chrome it drove me mad, because sometimes it passed successfully, and sometimes the ".click" didn't work and it would fail the test.
Took a long time to notice it, but the reason was: I used to sometimes minimize the browser to 80% to be able to see the browser along side my IDE. it appears that the ".click" doesn't work when I did it.
At least for me this was the issue