Mojolicious Tests: How to get the input value using css-selectors - html

I am writing a test for a Mojolicious Application, which sends some HTML form data and then checks, if they show up in the subsequent get request.
$t->post_ok('/intern/offer/edit' => form => {
'angebotsdatum' => '2014-02-22',
'gastname' => 'Hansi Hinterseer',
'einmalkosten' => '128.00',
'tage' => '9',
'ankunft' => '2014-01-01',
'gesamtpreis' => '764.00',
'abfahrt' => '2014-01-10',
'tagespreis' => '70.71',
'apartments_id' => 'HAG28',
'id' => '1',
'aufenthaltspreis' => '636.39'
}
)
->status_is(200)
->content_like( qr/Angbot bearbeiten/ )
;
$t->get_ok('/intern/offer/edit/1')
->status_is(200)
->text_like('html body h2' => qr/Intern - Angebote/ )
->text_like('html body h3' => qr/Angbot bearbeiten/ )
->text_is('html body form div#adatum label' => 'Angebotsdatum:' )
->text_is('html body form div#adatum input#angebotsdatum value' => '2014-02-22' )
;
Unfortunately the last test for the value of the input element fails, since the returned value is always empty. The test for the form-label (here 'Angebotsdatum:') succeeds.
How can I select and get back the input-elements value from a HTML-form?
The HTML-code of the form is:
<div id="adatum">
<label>Angebotsdatum:</label>
<input type="text" name="angebotsdatum" value="2014-02-22" id="angebotsdatum">
</div>
And this is the test-output:
# Failed test 'exact match for selector "html body form div\#adatum input[name=angebotsdatum] value"'
# at t/1210-workflow_booking.t line 80.
# got: ''
# expected: '2014-02-22'
So we can see clearly, that the CSS-selector returns the empty value.

From the Test::Mojo
The text_is - Checks text content of the CSS selectors first
matching HTML/XML element for exact match with at in Mojo::DOM.
The at method
Find first element in DOM structure matching the CSS selector and
return it as a Mojo::DOM object or return undef if none could be
found. All selectors from "SELECTORS" in Mojo::DOM::CSS are supported.
And the
html body form div#adatum input#angebotsdatum value
^^^^^^ - this isn't valid
IMHO, isn't valid CSS selector.
You can try the next (shortened) selector:
div#adatum > input[value="2014-02-22"]
so find the element <input> what has an attribute equal to 2014-02-22.
E[foo="bar"]
An E element whose foo attribute value is exactly equal to bar.
More info Mojo::DOM::CSS#SELECTORS
So, it is enough test the existence of the element exactly with the wanted value:
->element_exists('input[value="2014-02-22"]', '...');
Ps: I'm not an very experienced Mojo developer, so ...

input#angebotsdatum means you are looking for an <input> element with an id=angebotsdatum attribute, but what you want to look for is a name=angebotsdatum attribute. So I think the last test should look something like
->text_is('html body form div#adatum input[name=angebotsdatum] value' => ...)

Related

page element definition for cloned rows

I am using the page-object-gem and trying find the best way to define my page elements when a set of text_field have an infinite number of occurrences.
The HTML on page load is similar to the following:
<div><input id="dx_1_code" value=""/> <input id="dx_1_dos" onblur="clone($(this),false)" value=""/></div>
If the user tabs out of the last input then a new row is cloned with id values that increment with HTML like follows:
<div><input id="dx_2_code" value=""/> <input id="dx_2_dos" onblur="clone($(this),false)" value=""/></div>
<div><input id="dx_3_code" value=""/> <input id="dx_3_dos" onblur="clone($(this),false)" value=""/></div>
My first try was to define my class as follows:
class SamplePage
include PageObject
include DataMagic
text_field(:dx_1, :id => "dx_1_code")
text_field(:dx_2, :id => "dx_2_code")
text_field(:dos_1, :id => "dx_1_dos")
text_field(:dos_2, :id => "dx_2_dos")
end
However I quickly ended up with a lot of redundant entries.
Is there a better way to handle an unknown number or entries like this in terms of element setups and use of the populate_page_with method?
The elements are indexed, which makes them a good candidate for the indexed properties feature. The indexed_property lets you define locators where a number is substituted in when accessing the element. The page object would look like:
class MyPage
include PageObject
indexed_property(:dx, [
[:text_field, :code, {id: 'dx_%s_code'}],
[:text_field, :dos, {id: 'dx_%s_dos'}],
])
end
The first two rows would then be inputted using:
page = MyPage.new(browser)
page.dx[1].code = 'a'
page.dx[1].dos = 'b'
page.dx[2].code = 'c'
page.dx[2].dos = 'd'
Unfortunately there is no built-in way for the populate_page_with method to work with indexed properties. As with anything, you could hack in something. The populate_page_with method looks for an "element" method as well as a setter method. By adding your own to the page object, the method could be used.
class MyPage
include PageObject
indexed_property(:dx, [
[:text_field, :code, {id: 'dx_%s_code'}],
[:text_field, :dos, {id: 'dx_%s_dos'}],
])
# Method for inputting the various dx code/dos values based on a Hash
def dx=(values)
values.each_pair do |index, fields|
fields.each_pair do |field, value|
dx[index].send("#{field}=", value)
end
end
end
# This is so that populate_page_with can check that the element is enabled/visible
def dx_element
dx[1].code_element
end
end
This would give you the ability to use populate_page_with by sending a Hash where the keys are the index and the values are the fields/values for that index. The same inputting of the page that we did before can now be written as:
page = MyPage.new(browser)
page.populate_page_with(dx: {
1 => {code: 'a', dos: 'b'},
2 => {code: 'c', dos: 'd'}
})

Raw HTML in HelperList column

I have a HelperList in Prestashop (1.6) with a few columns/rows. One of the columns is an anchor element (a href), and I need to show it like that in the list, but Prestashop escapes the value and represents it as a literal string.
How can I show an actual anchor element in one of the columns of a HelperList?
Plus: I'd like to not have to override PS classes nor copy the entire template just to change a single line of code. I do know how to do it using either of those ways, but I'm looking for something less "aggressive".
You can use this trick:
$fields_list = array(
'your_link' => array(
'title' => $this->l('Your title'),
'type' => 'bool',
'float' => true, // a trick - prevents from html escaping
// else code
),
);

Cakephp 3.0 I would like to include a Year input field with a drop down, but it is inputing as an array

I have a Year field in a form and I am using FormHelper.
echo $this->Form->input('year', [
'type' => 'year',
'minYear' => date('Y')-10,
'maxYear' => date('Y')
]);
The table file validator looks like:
->add('year', 'valid', ['rule' => 'numeric'])
->allowEmpty('year')
I have a very similar input in another app that seems to work fine. I set the MySql column to int(5) to match what I had working elsewhere.
Checking debugkit it shows the "year" input as an array while the other inputs are strings. If I remove the validation rule it throws an illegal array to string conversion, so I assume this is where the error is.
Any help is greatly appreciated.
I have just tested with your above code and it is working fine for me. Try to delete the cache and check it once more.
Creates a select element populated with the years from minYear to maxYear. Additionally, HTML attributes may be supplied in $options. If $options['empty'] is false, the select will not include an empty option:
empty - If true, the empty select option is shown. If a string, that
string is displayed as the empty element.
orderYear - Ordering of
year values in select options. Possible values ‘asc’, ‘desc’. Default
‘desc’ value The selected value of the input.
maxYear The max year to
appear in the select element.
minYear The min year to appear in the
select element.
Try this one:
<?php
echo $this->Form->year('exp_date', [
'minYear' => date('Y')-10,
'maxYear' => date('Y'),
'id' => 'cc-year',
'class' => 'form-control',
'empty' => false,
'orderYear' => 'asc'
]);
?>
Official Documentation: CookBook - Creating Year Inputs

HTML::Template <TMPL_IF> blocks being skipped

I'm having trouble getting HTML::Template's <TMPL_IF> blocks to function -- it seems like my template is just skipping that code entirely.
<TMPL_LOOP NAME=DATA>
<TMPL_VAR NAME=complete><br>
<TMPL_IF NAME="complete">
<!-- Some HTML here -->
<TMPLE_ELSE>
<!-- Some other HTML here -->
</TMPL_IF>
</TMPL_LOOP>
The TMPL_VAR line is displaying the expected values, but nothing in the block below it is showing up whatsoever. The data structure I'm passing in to the template is:
$VAR1 = [
{
'code' => 26,
'message' => 'Start building sensors for Jarvis',
'complete' => 0
},
{
'code' => 33,
'message' => 'Machine learning to determine if actions are appropriate or not',
'complete' => 0
},
{
'code' => 37,
'message' => 'Play by genre audioserv method',
'complete' => 0
}
];
Any help is greatly appreciated -- I've been banging my head against it for the last hour.
From the fine manual:
The <TMPL_IF> tag allows you to include or not include a block of the template based on the value of a given parameter name. If the parameter is given a value that is true for Perl - like '1' - then the block is included in the output. If it is not defined, or given a false value - like '0' - then it is skipped.
All your completes are zero so <TMPL_IF> won't show anything. You might expect the "else" branch to be displayed but you don't have any <TMPL_ELSE> branches, you have <TMPLE_ELSE>. Fix the typo and try again.

How to assert that an input element is empty in Ruby on Rails tests

I want to ensure that the password fields are empty when editing a user. How do I do this in a functional test?
I've tried both of these variants:
assert_select "input[name=?][value=?]", 'user[password1]', ''
and
assert_tag :tag => "input", :attributes => {:name => "user[password1]", :value => ""}
Both fail because there is no value= attribute present in the generated html. I don't see any way of testing that an attribute is not present in the generated html?
Try this:
assert_select 'input:not([value])[name="user[password1]"]', true
in cucumber/webrat sth like page.should_not have_xpath("//input[contains(#value, \"\")]") works