Filling in text box with capybara - ruby

I have a text box that I'm trying to fill in with Capybara. I've tried to play around with it and try to figure something's out but my tests don't pass.
Here's
It's for this specific text box:
<span class="ui-grid-header-cell-label ng-binding" ui-grid-one-bind-id-grid="col.uid + '-header-text'" id="14213131-uiGrid-0008-header-text">DOB</span>
<input type="text" class="ui-grid-filter-input ui-grid-filter-input-0 ng-touched" ng-model="colFilter.term" ng-attr-placeholder="{{colFilter.placeholder || ''}}" aria-label="Filter for column" placeholder="" aria-invalid="false" style="">
Here's the code I have.
find('ui-grid-filter-input ui-grid-filter-input-0 ng-touched').set('1414234')
Ideally I'm trying to find this specific text box and type something in.

To fill the <input> using Capybara you can use either of the following locator strategies:
find('[aria-label=Filter for column]').set('1414234')
or
find('input[aria-label=Filter for column]').set('1414234')

As a CSS selector 'ui-grid-filter-input ui-grid-filter-input-0 ng-touched' is looking for a ng-touched element which is a descendant of a ui-grid-filter-input-0 element which is a descendant of a ui-grid-filter-input element - which obviously isn't what you want. Since you're trying to match on classes you need to use the CSS class selector which starts with .
find('.ui-grid-filter-input.ui-grid-filter-input-0.ng-touched')
would be the correct way to do what you were doing, however you probably don't really need all those classes, and the more you specify the more brittle you are making your selectors. It's likely that just
find('.ui-grid-filter-input-0').set('1414234')
would do what you want - or better
find('.ui-grid-filter-input-0').fill_in(with: '1414234')

Related

Finding and entering text in CapyBara

I'm currently trying to find this specific textbook and send keys to it. The problem that I'm having is I'm trying to use the find method. I tried a lot of variations on this textbox and was unable to find this textbook.
HTML TAG:
<div class="selectize-input items not-full ng-valid has-options ng-dirty"><input type="text" autocomplete="off" tabindex="0" style="width: 187.033px; opacity: 1; position: relative; left: 0px;" placeholder="Type a Catname or Kob name"></div>
Here's what I'm trying to do
find('selectize-input items not-full ng-valid has-options').sendkeys 'Meow'
Would there be an easy of doing this without using xpath if possible. Also how would I enter via send keys.
fill_in uses Capybaras :fillable_field selector which finds elements by id, name, placeholder, or associated label text. Therfore the easiest way of entering text in that field is to just do
fill_in('Type a Catname or Kob name', with: 'Meow')
Beyond that, you've recently posted a number of questions where you are mixing up CSS selectors. I think you would really benefit from using https://flukeout.github.io/ to learn and understand CSS selectors. You are mixing up element type selectors, class selectors, etc. If you really want to do it via class names of the parent element you could do something like
find('.selectize-input.items.not-full.ng-valid.has-options.ng-dirty input').send_keys('Meow')
but that's really a terrible, brittle way to do it. Notice in the CSS selector the .s in front of class names, space between parent and descendant selectors, no . in front of the element type selector, etc

Is there something special about a file type input that makes it not able to find?

I'm looking to add files to an <input type="file">
Here is a snippet of the html
<span class="btn btn-xs btn-primary btn-file"> #found
<span class="blahicon blahicon-upload"></span>
Browse
<input type="file" data-bind="value: fileName, event: { change: uploadImagesOnChange }"
accept="blah/txt" multiple=""> #not found
</span>
and here's the capybara and ruby
within_frame('frame1') do
within_frame('frame2') do
within(:xpath, [containing span xpath]) do # finds this
find(:xpath, './/*[#type="file"]').send_keys('C:\Users\...\blah.txt') #ElementNotFound
end
end
end
I see no hidden block and it's super scoped. Any thoughts?
Instead of using within(:xpath, [containing span xpath]) can you directly check the xpath of input like: has_xpath?(".//span[contains(text(),'Browse')]/input")
and if it is returning true then try with using
find(:xpath, ".//span[contains(text(),'Browse')]/input").send_keys ('C:\Users\...\blah.txt')
If you are aware about the 'pry' gem then you can debug this thing by trying various xpath combinations instead of just running the whole script, So you will get to know the actual problem.
I think there is mistake in your xpath
.//*[#type="file"]
Change to
.//*[#type='file']
as browser can detect attribute value with double quotes(" ") but inside script you need to use it in single quote (' ')
Also can make different combinations of your XPath like
//input[#type='file']
Judging by the class btn-file on the wrapper class, it's probable you're using Bootstrap and one of the "standard" methods to hide the actual file input element so that it can be style the same across multiple browsers. There are a number of ways of hiding the button from just setting display:none on it to the more "modern" method of expanding it to the same size as the replacement button and seeting it's opacity to 0 so it become a transparent overlay on the replacement.
The basic strategy to dealing with this kind of setup in Capybara is to use execute_script to make the element visible first and then use attach_file or set as normal. For instance if your site is using the opacity method of hiding the file element you could do something like
within_frame('frame1') do
within_frame('frame2') do
within(:xpath, [containing span xpath]) do # finds this
file_input = find(:file, visible: :all)
page.driver.browser.execute_script("$(arguments[0]).css('opacity',1)", file_input.native)
file_input.set('C:\Users\...\blah.txt')
end
end
end
Note - this code assumes you're using jQuery in your page and will only work with the selenium driver since it uses seleniums driver specific ability to pass elements from capybara to selenium in the execute_script call. If not using jQuery the JS will need to change and if using another driver you would need to find the element in the JS script using DOM methods and then modify its opacity.

How to fill timepicker field with capybara

I am new to capybara and I have some problems with text field, Capybara can not find the field.
I need to create automatic tests and one of them has to fill in fields that changes all the time(id and name changes, they are like this: id="patternDailyStart_146d7547140" and this number is always different).
Html part looks like this:
<div class="timepicker">
<input value="" id="patternDailyStart_146d7547140"
name="patternDailyStart_146d7547140"
class="timepicker-input patternDailyStart hasDatepicker"
type="text">
<img class="ui-datepicker-trigger"
src="/mpromoter/assets/4716a6a0a357181/app/components/timefield/clock.png"
alt="..."
title="...">
</div>
This is time picking field. And The problem is that capybara can not find the field.. however I try to find it for filling.
When I try to find this xpath, then it is found, but when I want to fill it in with time($starttime=17:00) then it says that element not found or it does not exist.
These xpaths are found:
page.has_xpath?('//tbody/tr/div/input[contains(., "patternDailyStart")]')
page.has_xpath?(:xpath, "//*[#class='timepicker-input patternDailyStart hasDatepicker']")
I tried to fill in like this:
And(/^fill up the fields$/) do
field = find("//*[#class='timepicker-input patternDailyStart hasDatepicker'")
field.set $starttime
end
And like this:
fill_in('timepicker-input.patternDailyStart.hasDatepicker', :with => $starttime)
And like this:
within(:xpath,'//tbody/tr/div/input[contains(., "patternDailyStart")]'){ fill_in("#patternDailyStart", with: $starttime)}
And many other ways but still nothing fills in those fields..
So I am asking for some help. What I have to do, any suggestions?
Thank you... :)
I think the easiest would be to locate the inputs by its 'patternDailyStart' class:
find(:css, '.patternDailyStart').set($starttime)

capybara ruby code to check an element is present or not

using capybara how can i check an element is present or not.
i used following code but it is not working
page.should_not have_selector('#confirmation_code')
<div style="width:250px;display:block;float:right;text-align:right;">
<span id="email_text">Order Number:<br></span>
<input id="confirmation_code" type="text">
</div>
i want to check above text box element is present or not?
So going from the last comment from Sush,
The first line in the code in the question is not correct at all. That will verify that the element is not shown.
You could use the following instead:
page.should have_css('#confirmation-code')
or if you wanted the text within do this:
page.find('#confirmation-code[type="text"]')
I will be honest though I am going by what I think the question is, it is not very clear what you are looking to achieve.

How to get value from a placeholder using xpath

All of the elements are dynamic. I can see only Placeholder which is unique from the following html:-
<input
id="ext-gen1617"
type="text"
size="20"
class="x-form-field x-form-text x-form-focus"
autocomplete="off"
aria-invalid="false"
placeholder="Gender"
data-errorqtip=""
role="textbox"
aria-describedby="combobox-1166-errorEl"
aria-required="true"
style="width: 78px;"
/>
I need to get the value displayed in
placeholder="Gender".
I tried using
//input[#placeholder='Gender']
But my webdriver script failed to identify it.
Can anyone please help me out with possible solution to it?
String s=driver.findElement(By.xpath("//input[#placeholder='Gender']")).getAttribute("placeholder");
System.out.println(s);
To get an attribute for a filed, you can use the .getAttribute() method.
I assume you are dealing with (front end)script generated web elements, then you must need to embrace lean way of thinking. Don't try to pull out a web element by it's property alone. If you are not getting them try to build a xpath from its parent or siblings.
say, the HTML goes like this,
<div id="somestatic id">
<div id="xyz">
<input name="dynamic one"/>
</div>
</div>
Then you can build a xpath as ,
//*[#id='staticID']/div/input
for the HTML,
<div id="staticID"></div>
<input name="dynamic one"/>
the xpath is ,
//*[#id='staticID']/following-sibling::input
similarly there are n number of option available. Give them a try
Try
driver.findElement(
By.cssSelector("input[id*='ext-gen']")
).getAttribute("placeholder")
Let me know is the above statement is working or not.
The best way is to find the element with CSS selector in this case -
input[placeholder='Gender'], which can easily find the element.

Resources