I have the scenario where selenium needs to open the login form and immediately after the page was loaded, click the "Log in" without entering anything. When nothing is filled the fields are both:
Surrounds are highlighted to red
Field name color changed is changed to red
"Required" string appears at the bottom of the field
I've got the whole test running, fields are located but I have no idea how to check (those point) correctly.
DOM only for one field (for the non-red form) is completely ugly:
<div class="form-row" xpath="1">
<div class="jss98 jss99 primary input outlined-input" input="[object Object]" meta="[object Object]">
<label class="jss113 jss102 jss107 jss110 jss112" data-shrink="false" for="email">Email</label>
<div class="jss133 jss120 jss134">
<fieldset aria-hidden="true" class="jss150 jss127" style="padding-left: 29.25px;">
<legend class="jss151" style="width: 0.01px;"><span></span></legend>
</fieldset>
<input aria-invalid="false" class="jss143 jss128" id="email" type="text" value="" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAjZJREFUWAntV7vKIlEMPt5dOy/NID9WIoKKCAsiWIqFFmLra4j2IoKPsL24YKWFD7Ai+ASClY2yNioWgjckfzLrCeN46XSKNXDmJPkyyWdOZnCE+CdfuP3G9RcXvHhRDapFNVUhZYXr1YX1+anmlwUvv3D9xPVu+YEFFRNeqCXKu6tf6i2IALXGMDEbVvlS+EPg/+tAuVwWmUyGR+/tHSgUCiKdThtHgCs/egosFouIRCIiEAjoY9n2+XwikUgIp9PJPq1itVpFLBYTfr9f636o8zs6GAzCeDwGKb1eD1wuF+OYARqNBpzPZzVkuVxCNpu9wuPxOEynU5kCWq0W2Gw2jhkOh1Cr1dgmVmyMRiO+USrNZpNxPD/p5n29XoPb7VZjTCYTTCYTxqRSqVQ4h54AD6HX6xXJZPKmTblcjn35fJ51qWBxkUqlVBM7KEKhkIR41+Zg50VhAofDQSBjPS72+z37tDo7Udntdqopdy1G+qP7CGMC2+1WdLtd8l0JniHb7Xb7hiSet8CjU2Nms5kYDAYcLxVtDunT7nw+Ho8HOp0OYDdgs9lAvV4Hs9nMON4EpVIJ5vO5Oog0M+Fw+ApXFAX6/T4cj0dYrVZQrVavcP0MEJGrALJpammg7mHS53A4nuJ2u/0uridgxYQ3cjqdbnx6B83MM8EOPIMZ4xlgjwHK3VYhj5f4i8UiRKNRzv35S2b4DHwIUAcWBjx5suSCCPyRlgG7WtvQj1P5o4kEfTK//fP8G/4x2UymA12DAAAAAElFTkSuQmCC"); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%; cursor: auto;">
</div>
</div>
</div>
DOM with "red":
<div class="form-row" xpath="1">
<div class="jss98 jss99 primary input outlined-input error " input="[object Object]" meta="[object Object]" aria-describedby="email-helper-text">
<label class="jss113 jss116 jss105 jss102 jss107 jss110 jss112" data-shrink="false" for="email">Email</label>
<div class="jss133 jss120 jss139 jss125 jss134">
<fieldset aria-hidden="true" class="jss150 jss127" style="padding-left: 29.25px;">
<legend class="jss151" style="width: 0.01px;"><span></span></legend>
</fieldset>
<input aria-invalid="true" class="jss143 jss128" id="email" type="text" value="" style="background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAmJJREFUWAntV7uKIkEUvbYGM4KID3wEIgjKRLLpKGLgFwiCfslGhkb7IbLgAzE1GhMxWxRRBEEwmEgDERWfW6fXuttq60a2wU6B1qlzb9U5fatsKROJVigUArvd7oeAyePx6Af3qGYymT7F2h8Wi+V7Pp+fmE7iv4Sw81GieusKIzNh4puCJzdaHIagCW1F4KSeQ4O4pPLoPb/3INBGBZ7avgz8fxWIxWIUCoX43Blegbe3NwoGg88zwMoncFUB8Yokj8dDdrv9MpfHVquV/H4/iVcpc1qgKAp5vV6y2WxaWhefreB0OimXy6kGkD0YDKhSqdB2u+XJqVSK4vE4QWS5XKrx0WjEcZ/PR9lslhwOh8p1Oh2q1Wp0OBw4RwvOKpBOp1kcSdivZPLvmxrjRCKhiiOOSmQyGXp5ecFQbRhLcRDRaJTe39//BHW+2cDr6ysFAoGrlEgkwpwWS1I7z+VykdvtliHuw+Ew40vABvb7Pf6hLuMk/rGY02ImBZC8dqv04lpOYjaw2WzUPZcB2WMPZet2u1cmZ7MZTSYTNWU+n9N4PJbp3GvXYPIE2ADG9Xqder2e+kTr9ZqazSa1222eA6FqtUoQwqHCuFgscgWQWC6XaTgcEiqKQ9poNOiegbNfwWq1olKppB6yW6cWVcDHbDarIuzuBBaLhWrqVvwy/6wCMnhLXMbR4wnvtX/F5VxdAzJoRH+2BUYItlotmk6nLGW4gX6/z+IAT9+CLwPPr8DprnZ2MIwaQBsV+DBKUEfnQ8EtFRdFneBDKWhCW8EVGbdUQfxESR6qKhaHBrSgCe3fbLTpPlS70M0AAAAASUVORK5CYII="); background-repeat: no-repeat; background-attachment: scroll; background-size: 16px 18px; background-position: 98% 50%;">
</div>
<p class="jss159 jss163 jss160" id="email-helper-text">Required</p>
</div>
</div>
We can see that: "class="jss98 jss99 primary input outlined-input error"/ aria-describedby="email-helper-text", input aria-invalid="true" and finally new paragraph was added with the text "Required"
What I would like to do right now is to check the field BEFORE it was clicked and check if those things listed above are nulls, next click and check if the elements previously not present are now present.
Could someone explain me how those three methods enclosed in the title are vary?
I would like to take the value? of class inside the div (class="jss98 jss99 primary input outlined-input"). Can someone tell me how it can be taken?
I'm writing in C#
The first thing you would want to do is put the before and after HTML in a diff engine to see what changed. (You can find a simple one online if you don't have one already.) There are three things I see (that I think are significant):
The class "error" is added to the outer DIV
The "aria-invalid" attribute on the INPUT changes from false to true
The P tag is added with id="email-helper-text" and contains "Required"
The before and after tests would go something like this... you do a .FindElements() (plural) and see if the count is 0 before and 1 after.
Here are some code samples
Example 1
By errorClassLocator = By.CssSelector("div.outlined-input.error");
// before
Assert.Zero(Driver.FindElements(errorClassLocator).Count, "Verify that 'error' class is not present");
// after
Assert.NotZero(Driver.FindElements(errorClassLocator).Count, "Verify that 'error' class is present");
Example 2
By ariaInvalidLocator = By.CssSelector("input#email[aria-invalid='true']");
// before
Assert.Zero(Driver.FindElements(ariaInvalidLocator).Count, "Verify that 'aria-invalid' attribute value of 'true' is not present");
// after
Assert.NotZero(Driver.FindElements(ariaInvalidLocator).Count, "Verify that 'aria-invalid' attribute is true");
NOTE: You could also use two locators... look for aria-invalid='false' for before instead of 'true' doesn't exist. Another option would be to find the element and then pull the value of 'aria-invalid' and compare it to 'true' or 'false'.
Example 3
By requiredLocator = By.Id("email-helper-text");
// before
Assert.Zero(Driver.FindElements(requiredLocator).Count, "Verify that the 'email-helper-text' P is not present");
// after
Assert.NotZero(Driver.FindElements(requiredLocator).Count, "Verify that the 'email-helper-text' P is present");
Assert.AreEqual("Required", Driver.FindElement(requiredLocator).Text, "Verify that 'Required' text is present");
NOTE: Using .FindElements() is crucial for the before case because if you use .FindElement() it will throw if the element is not found. It's also useful for the after case in case it's not present as expected. Instead of getting an ElementNotFoundException, you'll instead get a failed Assert with a clear message on what is missing.
You could basically use XPath to check for the contents of the class attribute like this:
"//div[contains(#class, 'error')]"
This should find nothing before you submit and find the colored element after submit.
Related
There is an element I can't figure out how to type text into it.
<div class="floatstart gridcell grideditablefield" colname="Items" coltype="string" coleditable="true" val="" style="width: 107px; overflow: hidden; cursor: text; height: 100%;"> </div>
Without code (manually) in order to put text in it I need to click on it twice, so in the code If I click on the element once, the class seems to change to:
<div class="floatstart gridcell grideditablefield activecell"...> </div>
And when I click on the element again it changes once more to
<div class="floatstart gridcell grideditablefield activecell NDColEditableInEdit"...> </div>
Anyway, once I try to send keys to it I get an Error:
OpenQA.Selenium.ElementNotVisibleException: 'element not interactable
(Session info: chrome=//doesn't matter)
(Driver info: chromedriver=//doesn't matter (6a5d10861ce8de5fce22564658033b43cb7de047-refs/branch-heads/4896#{#875}),platform=Windows NT 10.0.19042 x86_64)'
Code:
// It does find the right element
var element = driverReUse.FindElementByXPath("//*[#id='CalcOfAmmountsData']/div/div[2]/div/div[1]/div[2]");
element.Click();
element.Click();
element.SendKeys("keys");
Please help
Try the below,
Actions act = new Actions(driver);
act.moveToElement(driver.findElement(By.xpath("//[#id='CalcOfAmmountsData']/div/div[2]/div/div[1]/div[2]"))).doubleClick().build().perform();
act.sendKeys('Keys');
Please make the changed if any required for c#, in above.
Hope this answer your question.
Generally <div> tags are not interactable unless it contains the attribute contenteditable="true".
Deep Dive
As you mentioned, initially the <div> element is:
<div class="floatstart gridcell grideditablefield" colname="Items" coltype="string" coleditable="true" ...> </div>
After first click:
<div class="floatstart gridcell grideditablefield activecell" colname="Items" coltype="string" coleditable="true" ...> </div>
After second click:
<div class="floatstart gridcell grideditablefield activecell NDColEditableInEdit" colname="Items" coltype="string" coleditable="true" ...> </div>
As per this and this discussion either after the first or second click an <input> / <textarea> gets added, where you need to send the character sequence as follows:
// It does find the right element
var element = driverReUse.FindElementByXPath("//*[#id='CalcOfAmmountsData']/div/div[2]/div/div[1]/div[2]");
element.Click();
element.Click();
var input = driverReUse.FindElementByXPath("xpath_input_textarea");
input.SendKeys("keys");
I want to be able to send text to this text box element:
<form class="compose okform initialized">
<div class="border"></div>
<div id="message_9028519832635440005Container" class="inputcontainer textarea empty">
<textarea class="clone" placeholder="Compose your message" aria-hidden="true" style="height: 21px; width: 417px; line-height: 18px; text-decoration: none; letter-spacing: 0px;" tabindex="-1"></textarea>
<textarea id="message_9028519832635440005" placeholder="Compose your message" style="height: 39px;"></textarea>
<span class="okform-feedback message empty" style="height: 0"></span>
<div class="icon okicon"></div>
</div>
<button class="flatbutton" type="submit"></button>
<div class="draft_message"></div>
<label class="checkbox" for="enter_to_send_9028519832635440005"></label>
</form>
I'm not able to location the element by searching for part of the ID (the number after message_ is dynamically generated).
I've also tried this but I get an error saying "unknown error: cannot focus element":
var textBox = DriverActions.driver.FindElements(By.ClassName("inputcontainer"));
textBox[0].SendKeys("Why hello");
Try the following css
.inputcontainer.textarea.empty>textarea:nth-child(1)
I assumed you want the first text area box with placeholder="Compose your message"
if so, you can also use the following cssSelector
[placeholder='Compose your message'][class='clone']
Partial search with id is also possible. Assuming the Container part of the div's id is unique and static, you can do the following
[id$='Container']>textarea:nth-child(1)
On the other hand, if you want the second textarea just simply change the child index
[id$='Container']>textarea:nth-child(2)
And, here is the implementation
By byCss = By.CssSelector("[id$='Container']>textarea:nth-child(1)");
IWebElement textBox = driver.FindElement(byCss);
textBox.SendKeys("Why hello");
Try this XPath using starts-with
var textBox= DriverActions.driver.FindElement(By.XPath(".//textarea[starts-with(#id,'message_')]"));
textBox.SendKeys("Why hello");
The reason that you are getting the error could be because by your selector you will end up getting a div instead of a textBox that you need.
I am having trouble selecting an element as I keep getting the subject error.
Strangely it has worked once, and only once but then never since, using the exact same code.
R9_Automation.Logintest.Loginuser:
OpenQA.Selenium.ElementNotVisibleException : Element is not displayed
I have tried using, implicit and explict waits to no success, I have also tried clicking the element first as seen in the // code but this tells me the element cant be clicked as not visible.
My code is below:
public static void Enterusername(string username)
{
//Driver.Instance.FindElement(By.Id("txtUsername")).Click();
Driver.Instance.FindElement(By.Id("txtUsername")).SendKeys(username);
And the HTML is below:
<form name="aspnetForm" id="aspnetForm" action="" method="post">
<div id="container" style="top: 10px; margin-top: 249.56px; display: block;">
<div class="login">
<div class="figure">
<div class="flex-content">
<span class="siteStatusPlaceHolder">
<p class="message"/>
<fieldset class="user">
<label for="txtUsername">
<input name="ctl00$footerPlaceHolder$txtUsername" class="placeholder" id="txtUsername" type="text" AUTOCOMPLETE="off" placeholder="username"/>
Where have I gone wrong ?
I am trying to click on the div tag that has id="0". Although it can find that id, unable to click on it. clicking on other ids work.
This was working in Firefox 12 but failing in 13
I am using Selenium2 with C#
driver.FindElement(By.XPath("//div[#class='MenuItem' and #id='0']")).Click();
<div style="position: absolute; top: 72px; left: 9px; " id="file" class="Menu">
<div class="MenuItem" id="0"> <img src="images/UI/Icons/folder.png">Folder</div>
<div class="MenuItem" id="1"> <img valign="middle" src="images/UI/Icons/tree/folderBlogClosed.png">Blog</div>
<div class="MenuItem" id="2"> <img valign="middle" src="images/UI/Icons/folderBoard.png">Discussion Board</div>
</div>
Elements with ID attributes that start with numbers are invalid HTML. While most browsers will render this just fine, it's entirely possible that attempting to use JavaScript to locate the element by the ID (as Selenium WebDriver does) will fail.
Is there a reason you're using an XPath and not just selecting by the ID?
driver.FindElement(By.Id("0"));
HTML id's should be unique on a page.
I resolved this issue by using mouse actions
. Thank you all for your input.
Actions builder = new Actions(driver);
IWebElement tagElement = driver.FindElement(By.XPath("//div[#id='0' and #class='MenuItem']"));
//mouse hover on first item
builder.MoveToElement(tagElement).Perform();
//click on first item
driver.FindElement(By.XPath("//div[#id='0' and #class='MenuItem']")).Click();
In the default newly created MVC3 application, at the CRUD's Create view, the text box is implemented/called up as
<div class="editor-field">
#Html.EditorFor(model => model.EnrollmentDate)
#Html.ValidationMessageFor(model => model.EnrollmentDate)
</div>
And the resulted html view file for that block becomes
<div class="editor-field">
<input class="text-box single-line" data-val="true" data-val-required="The EnrollmentDate field is required." id="EnrollmentDate" name="EnrollmentDate" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="EnrollmentDate" data-valmsg-replace="true"></span>
</div>
I look up the class single-line in the Site.css but I can't find it anywhere, only multi-line there is [:-D silly inversion].
Could someone tell me where it is ? is it a css keyword ?
Second, I don't know the difference between using EditFor member function from Html class and TextBox function also from Html especially when I would like to add new style elements to the textbox.
[EDIT]
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-application
I am reading that tutorial
It's an emitted class attribute from a built-in editor template. This article explains them quite well.
http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html
Yes its a CSS style but it is not defined in the Site.css, the CSS that is applied in that instance is text-box and input[type="text"].
.text-box {
width: 30em;
}
input[type="text"],
input[type="password"] {
border: 1px solid #ccc;
padding: 2px;
font-size: 1.2em;
color: #444;
width: 200px;
}
Also you can use
#Html.TextBoxFor(model=>model.Name, new {#class="class-name"})
instead of
#Html.EditorFor()