Capybara "fill_in" by xpath? - automation

I'm running into some trouble attempting to fill_in a Text form on a form group.
HTML:
<div class="form-group">
<label class="control-label">First Name</label>
<input class="form-control" type="text" data-filter="0">
</div>
I've tried using fill_in via using the label text IE "First Name" with no luck; I've also tried using the "data-filter="0"" with no luck (I'm not even sure what this is; it doesn't seem to be an id of any sort).
I figured maybe I could use the xpath? but can you even do a finder on the xpath of something and then fill it in? I couldn't find anything that seemed to reference being able to in the capybara module docs.

An alternative would be to use find and set:
find(:xpath, "//label[text()='First Name']/following-sibling::input").set("text")
Or:
find(:xpath, "//div[label='First Name']/input").set("text")

Related

How can I find an element with unconstant id and name?

Well, I am new to selenium and trying to automate some form pages.
I was trying to locate and select the field below I pasted, but name and ID are changing every time the page loads. Is there any way to select that field with selenium?
I am using python btw in case that changes anything.
<dd>
<input type="text" class="input" name="0e9c304b1edf4e01c023790b6ee5442ac6663bf6" autocomplete="username" required="required" autofocus="autofocus" maxlength="25" id="_xfUid-4-1583549932">
</dd>
You can use the following xpath:
//dd/input[#class='input']
if there are other inputs then
//dd/input[#class='input'][1]
or you can try
//dd/input[#autocomplete='username']

Experience Editor input with placeholder rendering issue in Sitecore

this issue happened when a input DOM with placeholder in Sitecore Experience Editor, does someone know how to solve this?
<div class="form-group">
<input class="form-control" placeholder="#Html.Sitecore().Field("Placeholder_Test")" value="123" />
</div>
Thanks
When Sitecore renders #Html.Sitecore().Field in Experience Editor mode, it adds extra html layout around the field value to allow content authors to edit the text.
So your generated output is something like that:
<input class="form-control" placeholder="<code attr="blah">aa</code><span>this is a text</span>" value="123" />
As you can see, this is not a valid html. And that's why you see incorrect output in Experience Editor.
What it means? That you cannot edit attributes of inputs inside Experience Editor using #Html.Sitecore().Field.
The simplest solution is to just render the value there, like (replace Sitecore.Context.Item with your datasource if needed):
<input class="form-control" placeholder="#Sitecore.Context.Item["Placeholder_Test"]" value="123" />
And to use Edit Frame to allow editing the placeholder text ( https://www.google.com/search?q=sitecore+edit+frame )

Splinter Is it possible to use browser.fill without name as a query

I would like to use an absolute xpath to fill in a search bar. The ids and classes are dynamically generated and there is no name variable or instance. So it feels like I'm stuck without a tool to fill in boxes without the named variable.
Is there a way around this? Can I somehow change the absolute xpath to look like its a name assignment and then query and fill based on the new 'type' I assigned the absolute xpath?
Is there a method for this in Selenium if not available in Splinter?
I've select by CSS and I'm finding this error 'selenium.common.exceptions.InvalidElementStateException: Message: Element is not currently interactable and may not be manipulated'
Edit:
<div class="type-ahead-input-container" role="search">
<div class="type-ahead-input-wrapper">
<div class="type-ahead-input">
<label class="visually-hidden" for="a11y-ember10393">
Search
</label>
<!---->
<input id="a11y-ember10393" class="ember-text-field ember-view" aria-
autocomplete="list" autocomplete="off" spellcheck="false"
placeholder="Search" autocorrect="off" autocapitalize="off" role="combobox"
aria-expanded="true" aria-owns="ember11064" data-artdeco-is-focused="true"/>
<div class="type-ahead-input-icons">
<!---->
</div>
</div>
<!---->
</div>
</div>
As you have asked Is there a method for this in Selenium, the Answer is Yes.
Selenium supports Sikuli. Sikuli automates anything you see on the screen. It uses image recognition to identify and control GUI components. It is useful when there is no easy access to a GUI's internal or source code.
You can find more about Sikuli here.
Let me know if this answers your question.
When you get an error-message like that, it could be that your search result is not what you expected. It could be that you are getting more than one result, ie a list. On a list you can not input.
You can find the input boxes with an xpath, select the prefered one from the list (by trying) and put a text in it with the WebDriverElement _set_value method. That is not appropriate because of the _, but it is usefull.
input_list = browser.find_by_xpath('//div[#class="type-ahead-input"]/input[#class="ember-textfield ember-view"]')
input_list[1]._set_value('just a text to see whether it is working')

Why Behat/Mink cant't find input field by ID, only by name?

I am testing page with behat and filling form.
I have two password inputs in page html.
First is on top:
<input id="login_password_0" class="form-control " type="password" placeholder="Slaptažodis" autocomplete="off" name="password">
Second at the bottom:
<input id="password" class="form-control validate" type="password" value="" name="password">
Then I run behat/mink test with:
And I fill in "password" with "test"
It fills first one and I need second to be filled.
How to understand documentation, that element can be found and filled by 'id|name|label|value'.
P.S. Changing HTML is not an option.
Haven't tested but it looks like that Behat is performing a task only once. He has no idea that there could be two elements with the same name. "Name" attribute should be unique for one form. Otherwise, you'll be posting two elements with the same name.
Without fixing your HTML nothing is possible, unless you implement your own test which overcomes this issue. Now "password" is both "id" and 2x "name" attribute. Selector should be unique.

Can't select label by text when label contains more than text

I am driving myself bonkers with this.
I have three form fields in a form:
Customer: required dropdown field
Weight: required text field
Status: optional text field
Each element has that label. The required fields' labels contain a span with an asterisk.
I'm using Xpather in Chrome. When I search for this, I receive 2 results, when I should get 3:
//*[contains(text(),'t')]
This makes no sense to me At All.
Customer, which is working:
<label for='customer-field'>
<span class='required-marker'>*</span>
Customer
<input id='customer-field' type='text' />
</label>
Weight, which is not working:
<label class='control-label'>
<span id='ctl01_requiredMarker' class='required-marker'>*</span>
Weight
</label>
Status, which is working:
<label class='control-label'>
Status
</label>
The only workaround that works for me is removing the required marker from the Weight label container. However, that doesn't explain how "Customer" gets matched at all.
Noteworthy: I'm trying to automate testing this page, so I can't really remove that span tag.
What's going on? And/or what do I do?
Try changing your XPath to the following:
//*[text()[contains(.,'t')]]
The source of this fix breaks it down far better than I could've done, so refer to that for detailed explanation! I've tested it myself using the XPath Checker extension for Firefox, and it matches your three items.
Try with the below method
driver.findElement(By.xpath("//span[#class='required-marker']/..")).getText().contains("Weight")
Please Let me know above method is working or not.
I think your html is where the issue lies.
This is probably what your html should look like:
<span class='required-marker'>*
<label for='customer-field'>Customer</label>
<input id='customer-field' type='text' />
</span>
<span id='ctl01_requiredMarker' class='required-marker'>*
<label class='control-label'>Weight</label>
</span>
<label class='control-label'>Status</label>
Are you using Selenium or WebDriver? What does WebDriver return as a response? Also make sure you add a "." before the xpath like .//*[contains(text(),'t')]
What does this print?
List<WebElement> elements = driver.findElement(By.xpath(".//*[contains(text(),'t')]"));
s.o.p(elements.size());