find_field with Poltergeist/Capybara - cucumber

I have a problem with Poltergeist. I can’t get the driver to locate a field on a page. What I want to do is to execute some js to make sure that the input field is empty before I start adding new text. I have a field with a label os "Skill list" and id of "user_skill_list". In order to make the step more generic I want to find the field by the label name and then get the id.
And(/^I delete the content of "([^"]*)"$/) do |label|
field_id = page.find_field(label).native.attributes['id'].value
page.execute_script("$('#{field_id}').val('');")
end
Here's the error message:
#javascript
Scenario: Update user by removing # features/godmin/skills.feature:36
Given "Thomas" skills are "rspec, testing" # features/step_definitions/godmin_steps.rb:63
And I click on "Edit" for "Thomas" # features/step_definitions/godmin_steps.rb:43
And I delete the content of "Skill list" # features/step_definitions/godmin_steps.rb:69
Unable to find field "Skill list" (Capybara::ElementNotFound)
./features/step_definitions/godmin_steps.rb:70:in `/^I delete the content of "([^"]*)"$/'
features/godmin/skills.feature:39:in `And I delete the content of "Skill list"'
```
My cucumber set up is pretty basic.
# features/support/env.rb
...
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
Capybara.default_max_wait_time = 5
...
Thank you. Please let me know if I should clarify my question.

Assuming your html is something like
<label for="user_skill_list">Skill list</label>
<input id="user_skill_list"/>
Then
page.find_field('Skill list').set('')
should find the field and clear it. If it's not finding the element there are a couple of possibilities.
The element isn't visible on the page
There is CSS being applied that is changing the case of "Skill list"
There are typos in your html so the label isn't actually associated with the field. You can test this by just doing page.find_field('user_skill_list').set('') so the label isn't involved
Note: you can get the id by just doing page.find_field('Skill list')[:id] rather than having to resort to .native.xxxx - although it's not really needed for this use case

Related

Gravity Forms - Add different CSS classes to First and Last Name fields

In the Gravity Forms, First and Last name fields are actually inside the "Name" field.
I can add a CSS class to the Name field, but I cannot add different CSS classes to each First and Last name fields.
Is this possible? Is there a filter hook or something that I missed?
You can add an HTML field at the top of your form with the following script:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#input_60_58_3").addClass("milk");//replace '60' with your form id, replace "58" with the name field id, leave the 3 as that is needed to isolate the first name
jQuery("#input_60_58_6").addClass("cookies");//replace '60' with your form id, replace "58" with the name field id, leave the 6 as that is needed to isolate the last name
});
</script>

How to handle a system.InvalidOperationException when converting from System.windows.FormsMessageBox to Xceed.Wpf.Toolkit.MessageBox

I have a very bland messagebox asking my users a simple question (not yes or no). For quick development I used a simple System.Windows.Forms.MessageBox and worded the question ("If you want to choose 'A' click 'Yes' if you want to choose 'B' click 'No'"). Now I'm going back and improving the look and feel of my wpf application and I'm stuck trying to convert this MessageBox into something that looks good.
My preliminary search told me to use Xceed.Wpf.Toolkit.MessageBox to be able to create custom message box but I'm getting an exception when I'm trying to use it.
Old Code
DialogResult dialogResultForDataDisplay = System.Windows.Forms.MessageBox.Show("Yes: Display by properties \n \t Each row will contain data for a specific asset class in a specific submarket during a specific quarter. \n \n No: Display by quarters \n \t Each row will will show the change over time for a specific property of an asset class in a specific submarket.", "Data Grouping Format", MessageBoxButtons.YesNo);
New Code
Style style = new Style();
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "By Property"));
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.NoButtonContentProperty, "By Quarter"));
MessageBoxResult result = Xceed.Wpf.Toolkit.MessageBox.Show("How do you want your information displayed?", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes, style);
Console.WriteLine(result);
The new code is generating this exception: System.InvalidOperationException: 'The calling thread must be STA, because many UI components require this.'
How would you go about handling this exception?
One solution I found now is rapping it in an invoke method. If someone has a better solution please post.
MessageBoxResult result = MessageBoxResult.None;
System.Windows.Application.Current.Dispatcher.Invoke((Action)delegate
{
Style style = new Style();
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "Yes, FTW!"));
style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.NoButtonContentProperty, "Omg, no"));
result = Xceed.Wpf.Toolkit.MessageBox.Show("How do you want your information displayed?", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes, style);
}
Console.WriteLine(result);

Customize the search portlet in Plone for specific content types

I'm using the search portlet in certain areas of my website, but I'd like to restrict the results to only search for a specific content type: for example only search the news items, or only show Faculty Staff Directory profiles.
I know you can do this after you get to the ##search form through that "filter" list, but is there a way to start with the filter on, so that the "Live Search" results only show the relevant results (i.e. only news items or only profiles).
I suspect you know it already, but just to be sure: You can globally define which types should be allowed to show up in searchresults in the navigations-settings of the controlpanel, and then export and include the relevant parts to your product's GS-profile-propertiestool.xml.
However, if you would like to have some types excluded only in certain sections, you can customize Products.CMFPlone/skins/plone_scripts/livesearch_reply, which already filters the types, to only show "friendly_types" around line 38 (version 4.3.1) and add a condition like this:
Edit:
I removed the solution to check for the absolute_url of the context, because the context is actually the livesearch_reply in this case, not the current section-location. Instead the statement checks now, if the referer is our section:
REQUEST = context.REQUEST
current_location = REQUEST['HTTP_REFERER']
location_to_filter = '/fullpath/relative/to/siteroot/sectionId'
url_to_filter = str(portal_url) + location_to_filter
types_to_filter = ['Event', 'News Item']
if current_location.find(url_to_filter) != -1 or current_location.endswith(url_to_filter):
friendly_types = types_to_filter
else:
friendly_types = ploneUtils.getUserFriendlyTypes()
Yet, this leaves the case open, if the user hits the Return- or Enter-key or the 'Advanced search...'-link, landing on a different result-page than the liveresults have.
Update:
An opportunity to apply the filtering to the ##search-template can be to register a Javascript with the following content:
(function($) {
$(document).ready(function() {
// Let's see, if we are coming from our special section:
if (document.referrer.indexOf('/fullpath/relative/to/siteroot/sectionId') != -1) {
// Yes, we have the button to toggle portal_type-filter:
if ($('#pt_toggle').length>0) {
// If it's checked we uncheck it:
if ($('#pt_toggle').is(':checked')) {
$('#pt_toggle').click();
}
// If for any reason it's not checked, we check and uncheck it,
// which results in NO types to filter, for now:
else {
$('#pt_toggle').click();
$('#pt_toggle').click();
}
// Then we check types we want to filter:
$("input[value='Event']").click();
$("input[value='News Item']").click();
}
}
})
})(jQuery);
Also, the different user-actions result in different, inconsistent behaviours:
Livesearch accepts terms which are not sharp, whereas the ##search-view only accepts sharp terms or requires the user to know, that you can append an asterix for unsharp results.
When hitting the Enter/Return-key in the livesearch-input, the searchterm will be transmitted to the landing-page's (##search) input-element, whilst when clicking on 'Advanced search...' the searchterm gets lost.
Update:
To overcome the sharp results, you can add this to the JS right after the if-statement:
// Get search-term and add an asterix for blurry results:
var searchterm = decodeURI(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURI('SearchableText').replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")) + '*';
// Insert new searchterm in input-text-field:
$('input[name=SearchableText]').val(searchterm);
Update2:
In this related quest, Eric Brehault provides a better solution for passing the asterix during submit: Customize Plone search
Of course you can also customize the target of advanced-search-link in livesearch_reply, respectively in the JS for ##search, yet this link is rather superfluous UI-wise, imho.
Also, if you're still with Archetypes and have more use-cases for pre-filtered searchresults depending on the context, I can recommend to have a look at collective.formcriteria, which allows to define search-criteria via the UI. I love it for it's generic and straightforward plone-ish approach: catalogued indizi and collections. In contradiction to eea.facetednavigation it doesn't break accessibility and can be enhanced progressively with some live-search-js-magic with a little bit of effort, too. Kudos to Ross Patterson here! Simply turn a collection (old-style) into a searchform by changing it's view and it can be displayed as a collection-portlet, as well. And you can decide which criteria the user should be able to change or not (f.e. you hide the type-filter and offer a textsearch-input).
Watch how the query string changes when you use the filter mechanism on the ##search page. You're simply adding/subtracting catalog query criteria.
You may any of those queries in hidden fields in a search form. For example:
<form ...>
....
<input type="hidden" name="portal_type" value="Document" />
</form>
The form on the query string when you use filter is complicated a bit by its record mechanism, which allows for some min/max queries. Simple filters are much easier.

jqgrid - initial filter value not properly set when using searchoptions with dataUrl

I think this is a bug in jqGrid (I'm using version 4.4.0). In my colModel, this works fine:
stype:'select', searchoptions: {sopt: ['eq','ne'], value:"Red:Red;Green:Green;Blue:Blue"}
but this does not:
stype:'select', searchoptions: {sopt: ['eq','ne'], dataUrl:'rest/selectcolors'};
where the dataUrl is returning
<option value='Red'>Red</option><option value='Green'>Green</option><option value='Blue'>Blue</option></select>
The colors show up okay in the combobox with 'Red' as the default value but the filter is not correctly initialized unless the user changes the combobox filter by selecting 'Green' or 'Blue' (and then possibly going back and selecting 'Red'). If the user tries to filter without first changing the combobox value, no matches are found. This problem occurs upon initial use of the filter dialog and after resetting the filter dialog, so it is very confusing to the user.
Does anyone know of a workaround / fix for this?
in first sight your returned dataurl doesn't have
<select>
and it might be a mistake
however, i have this problem too!
but i don't find any solution by search on web.
i resolve this problem temporary by a trick
i add one option with value = -1 and text "Please Select"
then in change event i remove this option
searchoptions: {sopt: ['eq', 'ne'], dataUrl:'yoururl',
dataEvents:[{ type: 'change',
fn: function(e)
{
$('td.data').find('option[value=-1]').remove();
}
}]},
but the problem still exist.. if user doesn't change combobox and select "Please Select" option, he will see an error.
i use the folowing code in my php url
echo "<select>";
echo "<option value='-1'>please select</option>";
while($row = pg_fetch_assoc($res))
{
echo "<option value='".$row['cid']."' >".$row['cname']."</option>";
}
echo"</select>";
you can use an style like this and remove it after change for select element
style='font-style:italic; color:gray; width:100px' data-native-menu='false'

magento exclude bundled items from search results

Currently, when one searches for an item, the quick search also brings up any bundles that contain items that fit the search criteria. How would I stop this?
A solution that filters out all bundled items from search results all together would be fine too.
UPDATE
I don't want the items to show in either the catalogue or search, but am using them as upsell items. This seems to leave two options:
I could amend the search results controller to omit bundled items (the method I was asking about), or
I could change the Upsell.php script to include "Don't show individually" items.
The second is perhaps easier? Currently the filter applied is:
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_itemCollection);
How would I change this so it shows don't show individually items?
Apologies for the incomplete initial question.
Second Update:
Ok, I've added
->setVisibility(null)
and it already has
->addStoreFilter()
But there is no change.
Essentially, if I don't have either of:
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_itemCollection);
Then I get the following error:
SELECT 1 AS status, e.entity_id, e.type_id, e.attribute_set_id, price_index.price, price_index.tax_class_id, price_index.final_price, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS minimal_price, price_index.min_price, price_index.max_price, price_index.tier_price, e.name, e.short_description, e.sku, e.price, e.special_price, e.special_from_date, e.special_to_date, e.manufacturer, e.manufacturer_value, e.small_image, e.thumbnail, e.news_from_date, e.news_to_date, e.tax_class_id, e.url_key, e.required_options, e.image_label, e.small_image_label, e.thumbnail_label, e.price_type, e.weight_type, e.price_view, e.shipment_type, e.links_purchased_separately, e.links_exist, e.is_imported, e.rc_manufacturer, e.rc_manufacturer_value, e.rc_vehicle, e.rc_vehicle_value, e.rc_assembly_type, e.rc_assembly_type_value, e.surface_type, e.surface_type_value, e.rc_drive, e.rc_drive_value, e.rc_scale, e.rc_scale_value, e.rc_motor_type, e.rc_motor_type_value, e.rc_engine_start_type, e.rc_engine_start_type_value, e.rc_engine_size, e.rc_engine_size_value, e.rc_form_factor, e.rc_form_factor_value, e.rc_frequency, e.rc_frequency_value, e.rc_gear_material, e.rc_gear_material_value, e.rc_operation, e.rc_operation_value, e.rc_torque_6v, e.rc_torque_6v_value, e.rc_speed_6v, e.rc_speed_6v_value, e.rc_bearing_type, e.rc_bearing_type_value, e.rc_waterproofing, e.rc_waterproofing_value, e.rc_battery_application, e.rc_battery_application_value, e.rc_input_supply, e.rc_input_supply_value, e.rc_power_output_amps, e.rc_power_output_amps_value, e.rc_power_output_watts, e.rc_power_output_watts_value, e.rc_lead_connector_type, e.rc_lead_connector_type_value, e.rc_gear_pitch, e.rc_gear_pitch_value, e.rc_nitro_content, e.rc_nitro_content_value, e.rc_exhaust_type, e.rc_exhaust_type_value, e.rc_engine_starter_type, e.rc_engine_starter_type_value, e.rc_head_fitting, e.rc_head_fitting_value, e.rc_temperature_rating, e.rc_temperature_rating_value, e.rc_oil_type, e.rc_oil_type_value, e.rc_container_size, e.rc_container_size_value, e.rc_class, e.rc_class_value, e.rc_paint_application, e.rc_paint_application_value, e.rc_size, e.rc_size_value, e.rc_colour, e.rc_colour_value, e.rc_pack_contents, e.rc_pack_contents_value, e.rc_spare_part_type, e.rc_spare_part_type_value, e.rc_oil_weight, e.rc_oil_weight_value, e.rc_glue_type, e.rc_glue_type_value, e.rc_usage, e.rc_usage_value, e.rc_tool_type, e.rc_tool_type_value, e.rc_engine_spare_type, e.rc_engine_spare_type_value, e.rc_tune_up_type, e.rc_tune_up_type_value, e.rc_bearing_pack_type, e.rc_bearing_pack_type_value, e.rc_driver_type, e.rc_driver_type_value, e.rc_nut_type, e.rc_nut_type_value, e.rc_plane_type, e.rc_plane_type_value, e.rc_boat_type, e.rc_boat_type_value, e.pre_order, e.pre_order_value, e.msrp_enabled, e.msrp_display_actual_price_type, e.msrp, links.link_id, link_attribute_position_int.value AS position FROM catalog_product_flat_1 AS e
INNER JOIN catalog_product_index_price AS price_index ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0
INNER JOIN catalog_product_link AS links ON links.linked_product_id = e.entity_id AND links.link_type_id = 4
LEFT JOIN catalog_product_link_attribute_int AS link_attribute_position_int ON link_attribute_position_int.link_id = links
I've also tried the following, but get the error:
Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this->_itemCollection);
Thanks for the help.
Based on your updated question:
If you are not using Enterprise Edition TargetRule or some other module which automates upsells (i.e. the upsells are defined explicitly by the admin), then likely the simplest approach is that which you've specified - rewrite the Upsell block to not add the visibility filter. As a guess, to be optimal you may want to call setVisibility(null) and addStoreFilter() on the collection to trigger normal limiting behavior.
EDIT: Original answer below
Admin > Catalog > Manage Products grid
Choose "Bundle Product" from the filters area at the top, click "Search"
Click "Select All"
Select "Update Attributes" from the mass action block's "Action" dropdown, click "Submit"
Change the "Visibility" attribute to "Catalog"
I solved it by modifying the custom module so that I didn't need to worry about this. It may be of some use as it involved using:
$collection->addAttributeToFilter('type_id', array('neq' => 'bundle'));
Which just excludes all bundle items from a collection.

Resources