4teamwork / ftw.testbrowser

A testing browser for Plone.
http://ftwtestbrowser.readthedocs.io/
5 stars 1 forks source link

Autocomplete widget: extract URL from javascript. #27

Closed jone closed 9 years ago

jone commented 9 years ago

The problem is that the browser-url may be wrong after a post (such as when creating a portlet). For actually doing the same as in the real-world, we need to extract the URL from the generated javascript.

/ @mbaechtold

:construction: @phgross @lukasgraf this might not work with the jQuery UI version of the autocomplete widget because of different javascript code. Can anybody verify if it works and maybe post the the JS so that we can make it work for both versions?

mbaechtold commented 9 years ago

Cool. This solves my problem (query for the values of a plone.formwidget.autocomplete.widget.AutocompleteMultiFieldWidget of a portlet field).

lukasgraf commented 9 years ago

@jone it almost worked. The JS for our widget looks like this (prettyfied):

function htmlDecode(input) {
    return $('<div/>').html(input).html();
}
$(function($) {
    $('#form-widgets-responsibles-input-fields').data('klass', 'autocomplete-multiselection-widget required list-field').data('title', 'None').data('input_type', 'checkbox');
    $('#form-widgets-responsibles-buttons-search').remove();
    $('#form-widgets-responsibles-widgets-query').autocomplete({
        source: 'http://nohost/plone/dossier-1/task-1/@@delegate_recipients/++widget++responsibles/@@autocomplete-search',
        minLength: 2,
        select: function(event, ui) {
            var field = $('#form-widgets-responsibles-input-fields input[value="' + ui.item.value + '"]');
            if (field.length == 0) {
                var itemCount = $('#form-widgets-responsibles-input-fields input').length;
                $('#form-widgets-responsibles-input-fields').append(htmlDecode("<span id='form-widgets-responsibles-" + itemCount + "-wrapper' class='option'><" + "input type='checkbox' id='form-widgets-responsibles-" + itemCount + "' name='form.widgets.responsibles:list' class='autocomplete-multiselection-widget required list-field' checked='checked' value='" + ui.item.value + "' /><label for='form-widgets-responsibles-" + itemCount + "'><span class='label'>" + ui.item.label + "</span></label></span>"));
            } else {
                field.prop('checked', true);
            }
            $('#form-widgets-responsibles-widgets-query').attr('value', '');
            event.preventDefault();
        }
    });
});

Original (unprettyfied):

function htmlDecode(input){ return $('<div/>').html(input).html(); } $(function($) { $('#form-widgets-responsibles-input-fields').data('klass','autocomplete-multiselection-widget required list-field').data('title','None').data('input_type','checkbox'); $('#form-widgets-responsibles-buttons-search').remove(); $('#form-widgets-responsibles-widgets-query').autocomplete({ source: 'http://nohost/plone/dossier-1/task-1/@@delegate_recipients/++widget++responsibles/@@autocomplete-search', minLength: 2, select: function(event, ui) { var field = $('#form-widgets-responsibles-input-fields input[value="' + ui.item.value + '"]'); if(field.length == 0) { var itemCount = $('#form-widgets-responsibles-input-fields input').length; $('#form-widgets-responsibles-input-fields').append(htmlDecode("<span id='form-widgets-responsibles-" + itemCount + "-wrapper' class='option'><" + "input type='checkbox' id='form-widgets-responsibles-" + itemCount + "' name='form.widgets.responsibles:list' class='autocomplete-multiselection-widget required list-field' checked='checked' value='" + ui.item.value + "' /><label for='form-widgets-responsibles-" + itemCount + "'><span class='label'>" + ui.item.label + "</span></label></span>")); } else { field.prop('checked', true); } $('#form-widgets-responsibles-widgets-query').attr('value', ''); event.preventDefault(); } }); });

So the relevant call to the autocomplete function looks like this:

$('#widget').autocomplete({ source: 'http://nohost/plone/dossier-1/task-1/@@delegate_recipients/++widget++responsibles/@@autocomplete-search', more: 'stuff'})

Changing the regex to add an additional [^']* before the single quote that marks the beginning of the URL works for our widget. With this change our tests (for our forms and the specific test for the autocomplete widget query) pass again.

diff --git a/ftw/testbrowser/widgets/autocomplete.py b/ftw/testbrowser/widgets/autocomplete.py
index bf12d0f..d6a8139 100644
--- a/ftw/testbrowser/widgets/autocomplete.py
+++ b/ftw/testbrowser/widgets/autocomplete.py
@@ -66,7 +66,7 @@ class AutocompleteWidget(PloneWidget):

     def _get_query_url(self):
         javascript = self.css('script').first.text
-        url = re.search(r"\)\.autocomplete\('([^']*)'", javascript).group(1)
+        url = re.search(r"\)\.autocomplete\([^']*'([^']*)'", javascript).group(1)
         return url

     def _resolve_objects_to_path(self, values):
jone commented 9 years ago

@lukasgraf I've updated the regexp as you proposed.

lukasgraf commented 9 years ago

:+1:

jone commented 9 years ago

merci :wink:

jone commented 9 years ago

@mbaechtold released 1.16.1

mbaechtold commented 9 years ago

Cool, thank you very much.