Test should: 1.click on icon 'Edit' row (form fot password changing is apperared); 2. Type a new 'password' ; 3. Click 'OK' button in form.
How its works on Watir + Ruby :
browser.img(:title, "Edit").click #fire_event 'onclick'
browser.text_field(:id,"ID").set 'password' # Set new password
browser.div(:id,"ID").click # Save a password
And password was changed - thats ok.
But when I tried to do the same on Selenium Webdriver + C# password isnt changed.
Code:
driver.FindElement(By.Id(...)).FindElements(By.TagName("img"))[0].Click(); // thats Edit button
driver.FindElement(By.Id(...)).SendKeys("1"); // Typed new password in row
driver.FindElement(By.Id(...)).Click(); // thats 'OK' button.
Guys what I did wrong?
I hope for your help.
If both the textbox and button have the same ID, there's your problem. It's impropper to have more than one instance of an ID per a page. Even if the element type is different, it shouldn't happen. Chrome assumes proper html therefore when you search for an element with an id of 'ID', it grabs the first instance. Here is a work around for that issue:
Open page in Chrome
Right click and "Inspect element" on the element you want to find (one of the elements with duplicate IDs)
Double click on the id that shows up and delete the id='ID' part and hit enter
Right click on that html element again and copy xpath
Change the selector to driver.FindElement(By.XPath("theXpathChromeReturns"));
Also you should check out css & xpath selection for the first element. It makes finding elements much cleaner.
driver.FindElements(By.CssSelector("#myId img")[0].Click();
or
driver.FindElement(By.CssSelector("img[title='edit']");
Related
Trying to click Sign In button but getting "Stale element Exception error".
IWebElement email = driver.FindElement(By.XPath("//*[contains(#name,'loginfmt')]"));
IWebElement password = driver.FindElement(By.XPath("//*[contains(#name,'passwd')]"));
IWebElement signIn = driver.FindElement(By.XPath("//*[contains(#id,'idSIButton9')]"));
IWebElement signInbtn = driver.FindElement(By.XPath("//*[#id='idSIButton9']"));
IWebElement signInbtn1 = driver.FindElement(By.XPath("//input[#type='submit']"));
email.SendKeys("automate#outlook.com");
email.SendKeys(Keys.Enter);
Thread.Sleep(1000);
password.SendKeys("Abc*123$");
password.SendKeys(Keys.Enter);
signInbtn1.Click();
Error:
OpenQA.Selenium.StaleElementReferenceException : stale element
reference: element is not attached to the page document
The reason of getting the StaleElementReferenceException is that the driver have found the element, but the page refreshed by the moment, you try to interract it, so element state is stale.
Try to initialize the element signInbtn1 after you fill the password field:
password.SendKeys("Abc*123$");
password.SendKeys(Keys.Enter);
IWebElement signInbtn1 = driver.FindElement(By.XPath("//input[#type='submit']"));
signInbtn1.Click();
I wasn't using C# for the test script, but I'm calling the selenium driver via javascript (within a jest test) and was getting the same problem for that specific Login Modal you mentioned.
Looking at the HTML in dev tools, I found that there is a subtle issue when using the ID ("idSIButton9") as the button element will change once the email has been entered in.
ie. The button element's value will change from 'Next' to "Sign in"
I found that using the id twice to identify the same button element results in the stale element issue.
So, for the second time round, I found the button element using the following xpath
"//input[#value='Sign in']"
This is much more specific than the id in this case.
Hope that helps.
I am using Selenium with .NET.
The WebDriver I am using is ChromeDriver.
I wrote a code, which fills a simple form (survey; from surveymonkey.com). The DOM Tree gets changed (manipulated) perfectly as I want it to.
But as soon as I click the button to submit the data (the survey/form), I get an error from the survey page, i.e. “please answer the question(s) x,y,...,n.” I verified the DOM Tree after getting this error, and amazingly, the DOM Tree has changed back to default, as there was never a change, except to the Input and TextArea Fields – these two nodes have been accepted from the page (the manipulation from selenium to the TextArea and Input Fields were accepted). So all manipulation on the Radio Buttons and Checkboxes has changed back to unchecked when clicking on the send button.
What I did:
I set a breakpoint before clicking on the button, copied the DOM Tree and compared that one with the DOM Tree of a real client: There was no difference except on the meta node (some query parameters of a script).
So I was really confused, why the survey won't work with selenium but with a real client, even though the DOM Tree are the same.
Therefore, I tried it with another Driver (with IE and Firefox) - I had the exact same problem.
Since the DOM Tree are the same (selenium and real client), I think there is a problem with the selenium Click event? Btw, I also tried, instead of Click(), to submit the form by Keys.Enter - it did not work as well.
Here is the link of the survey (to get the DOM Tree): https://de.surveymonkey.com/r/KZDWJD2?pharmacy=test
Example: For the Radio buttons, what I did (and the only thing which is necessary) was changing/manipulating the attribute aria-checked from false to true. As soon as I submitted the survey, this attribute changes back to false, which seems really strange to me and therefore cannot be send to the backend (message in the frontend: 'please answer the question 1,2,...,n).
Here is some code from my C#:
Changing the above attribute: `
public static void SetAttribute(this IWebElement webElement, string name, string value)
{
var driver = ((IWrapsDriver)webElement).WrappedDriver;
var jsExecutor = (IJavaScriptExecutor)driver;
jsExecutor.ExecuteScript("arguments[0].setAttribute(arguments[1], arguments[2]);", webElement, name, value);
}
As already mentioned, the attribute gets changed perfectly by above method. But, as soon as selenium submits the survey (by clicking on the button), the attribute gets changed back to false and the survey can therefore not be sent.
Any help or advice would be appreciated.
Thanks in advance.
After some more digging I found out, that survey monkey adds another attribute to every input field: checked="checked" - adding this attribute to the specific node elements was the key to the solution - the survey can now be sent.
I am trying to create this simple test where you head to the URL, enter your login credentials and then click the button to sign in. It is doing everything, except for clicking the button. I am trying to doing it by calling up ClassName. Can anyone look at my test and see what I am doing wrong?
public void test_search()
{
var driver2 = new ChromeDriver(#"C:\Users\MyName\Desktop\NUnitTestProject1\NUnitTestProject1\bin\Debug\netcoreapp2.1");
driver2.Navigate().GoToUrl("https://portal.crushdata.com/");
driver2.FindElement(By.Name("Email")).SendKeys("email#email.com");
driver2.FindElement(By.Name("Password")).SendKeys("Password");
driver2.FindElement(By.ClassName("btn bg-teal btn-block btn-lg waves-effect")).Click();
}
This is my classname for my button.
Use CSS selector as shown below:
By.ClassName("btn.bg-teal.btn-block.btn-lg.waves-effect")
Each dot represents a class.
See this page for more info and here is an example from that page:
.name1.name2
Selects all elements with both name1 and name2 set within its class attribute
To click on the SIGN IN button you have to induce WebDriverWait for the desired ElementToBeClickable() and you can use either of the following Locator Strategies:
CssSelector:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("button.btn.bg-teal.btn-block.btn-lg.waves-effect"))).Click();
XPath:
new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//button[text()='SIGN IN']"))).Click();
Try making use of the button xpath.
Open the dev tools. Right click on the button you want to be clicked > Select Inspect >Then right click the html in the dev tools window and Copy Xpath from the Copy option.
Then in you code replace FindElement with FindElementByXPath:
driver2.FindElementByXPath("//*xpath/goes/here")).Click();
Given your shared html block, the following XPath will suffice.
//div[contains(#class = "text-center")]//button[contains(#class, 'btn bg-teal btn-block btn-lg waves-effect') and #type = 'submit']
If the driver is still unable to click you should consider the following:
Is the XPath unique? paste the xpath in chrome's devtools search box in the inspect element tab and make sure the provided xpath is targeting the element you are intending. If this is not the case then you should make the xpath more unique.
Is the element in an iframe? if the element is in an iframe the driver won't be able to locate it by default. In such cases you will need to first switch to the iframe and then attempt to locate and interact with the element.
Is the element clickable, visible and enabled? To check these properties first find the element and store in a separate variable and then check the said properties are true.
could someone help in with this problem with newest update of chrome (version 59.0.3071.115)?
Our login form has 3 textbox instead of normal 2. First is the schema name (e.g country code), second is username (e.g anonymous), last is password (e.g ****). We use codebehind this.schemaname.Focus(); to focus in this first textbox when user open login form.
But now when user save username, password, chrome use autofill then focus to second textbox - usename, instead of default first textbox (schemaname). And this is my problem.
It begin from 2017/06/29, maybe newest update from chrome version 59.0.3071.115.
So how to config this new chrome for this problem, or anyway to set programmatically by C# codebehind or javascript/JQuery for Asp.Net?
Thank for any help!
I'm trying to build my first test with selenium and got a problem.
I'm searching for a element, no problem. I can click on it, get the
text in the element... every thing works fine.
But double click on the element just doesn't work. Selenium
clicks in the wrong location. I made a screenshot of this situation:
Screenshot
To find the row i use xpath and search for the text in the cell, but this text is unique(I checked it)
private readonly string _identityPath = ".//td[.= 'All Employees']";
...
mainPage.FindElement(By.XPath(_identityPath)).Click(); //Works(dotted box)
Actions builder = new Actions(mainPage);
IAction doubleClick = builder.DoubleClick(mainPage.FindElement(By.XPath(_identityPath))).Build();
doubleClick.Perform(); //wrong location/element
/*
Actions action = new Actions(mainPage);
action.DoubleClick(mainPage.FindElement(By.XPath(_identityPath)));
action.Perform(); *///wrong location/element
This page is in an iframe and the grid is a dojo component... maybe the problem
comes from there. Any ideas whats wrong? I have no idea where this is coming from. :/
Greets
It is common issue that Actions builder does not work.
Using JavaScript should help - find answer in this thread:
Selenium 2/Webdriver - how to double click a table row (which opens a new window)
If the element is in an iframe, you need to switch to that iframe in order to interact with the element.