Commit e994dea0 authored by Andrew Nicols's avatar Andrew Nicols
Browse files

MDL-62514 behat: Rewrite handling of autocomplete

This includes a minor restructure of the autocomplete JS to make use of
promises and improve tracking of pending JS.

In particular it improves the way in which throttled text input is
handled to ensure that the behat does not continue until:
- typing is fully complete; and
- all possible ajax requests have been sent; and
- all possible ajax requests complete; and
- the suggestions are updated.

A number of conditions existed where behat would move on to the next
step too early in a race condition effect between Behat and Autocomplete.
parent 7bfb575f
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
This diff is collapsed.
......@@ -47,13 +47,45 @@ class behat_form_autocomplete extends behat_form_text {
if (!$this->running_javascript()) {
throw new coding_exception('Setting the valid of an autocomplete field requires javascript.');
}
$this->field->setValue($value);
// After the value is set, there is a 400ms throttle and then search. So adding 2 sec. delay to ensure both
// throttle + search finishes.
sleep(2);
$id = $this->field->getAttribute('id');
$js = ' require(["jquery"], function($) { $(document.getElementById("'.$id.'")).trigger("behat:set-value"); }); ';
$this->session->executeScript($js);
$this->key_press(27);
// Set the value of the autocomplete's input.
// If this autocomplete offers suggestions then these should be fetched by setting the value and waiting for the
// JS to finish fetching those suggestions.
$istagelement = $this->field->hasAttribute('data-tags') && $this->field->getAttribute('data-tags');
if ($istagelement && false !== strpos($value, ',')) {
// Commas have a special meaning as a value separator in 'tag' autocomplete elements.
// To handle this we break the value up by comma, and enter it in chunks.
$values = explode(',', $value);
while ($value = array_shift($values)) {
$this->set_value($value);
}
} else {
$this->field->setValue($value);
$this->wait_for_pending_js();
// If the autocomplete found suggestions, then it will have:
// 1) marked itself as expanded; and
// 2) have an aria-selected suggestion in the list.
$expanded = $this->field->getAttribute('aria-expanded');
$suggestion = $this->field->getParent()->find('css', '.form-autocomplete-suggestions > [aria-selected="true"]');
if ($expanded && null !== $suggestion) {
// A suggestion was found.
// Click on the first item in the list.
$suggestion->click();
} else {
// Press the return key to create a new tag.
// Note: We cannot use $this->key_press() because the keyPress action, in combination with the keyDown
// submits the form.
$this->field->keyDown(13);
$this->field->keyUp(13);
}
$this->wait_for_pending_js();
$this->key_press(27);
}
}
}
......@@ -36,7 +36,7 @@
{ "inputID": 1, "suggestionsId": 2, "selectionId": 3, "downArrowId": 4, "placeholder": "Select something" }
}}
{{#showSuggestions}}
<input type="text" id="{{inputId}}" list="{{suggestionsId}}" placeholder="{{placeholder}}" role="combobox" aria-expanded="false" autocomplete="off" autocorrect="off" autocapitalize="off" aria-autocomplete="list" aria-owns="{{suggestionsId}} {{selectionId}}"/><span class="form-autocomplete-downarrow" id="{{downArrowId}}">&#x25BC;</span>
<input type="text" id="{{inputId}}" list="{{suggestionsId}}" placeholder="{{placeholder}}" role="combobox" aria-expanded="false" autocomplete="off" autocorrect="off" autocapitalize="off" aria-autocomplete="list" aria-owns="{{suggestionsId}} {{selectionId}}" {{#tags}}data-tags="1"{{/tags}}/><span class="form-autocomplete-downarrow" id="{{downArrowId}}">&#x25BC;</span>
{{/showSuggestions}}
{{^showSuggestions}}
<input type="text" id="{{inputId}}" placeholder="{{placeholder}}" role="textbox" aria-owns="{{selectionId}}"/>
......
......@@ -138,10 +138,6 @@ Feature: Mapping courses in a feedback
And I follow "Map feedback to courses"
And I set the field "Courses" to "Course 2"
And I set the field "Courses" to "Course 3"
# Weird solution to make the editable field to lose the focus
# but with the focus, "save changes" uses to fail because of
# the suggestions hiding the button.
And I press key "27" in the field "Courses"
And I press "Save changes"
And I should see "Course mapping has been changed"
And I log out
......
......@@ -36,7 +36,7 @@
{ "inputID": 1, "suggestionsId": 2, "selectionId": 3, "downArrowId": 4, "placeholder": "Select something" }
}}
{{#showSuggestions}}
<input type="text" id="{{inputId}}" class="form-control" list="{{suggestionsId}}" placeholder="{{placeholder}}" role="combobox" aria-expanded="false" autocomplete="off" autocorrect="off" autocapitalize="off" aria-autocomplete="list" aria-owns="{{suggestionsId}} {{selectionId}}"/><span class="form-autocomplete-downarrow" id="{{downArrowId}}">&#x25BC;</span>
<input type="text" id="{{inputId}}" class="form-control" list="{{suggestionsId}}" placeholder="{{placeholder}}" role="combobox" aria-expanded="false" autocomplete="off" autocorrect="off" autocapitalize="off" aria-autocomplete="list" aria-owns="{{suggestionsId}} {{selectionId}}" {{#tags}}data-tags="1"{{/tags}}/><span class="form-autocomplete-downarrow" id="{{downArrowId}}">&#x25BC;</span>
{{/showSuggestions}}
{{^showSuggestions}}
<input type="text" id="{{inputId}}" placeholder="{{placeholder}}" role="textbox" aria-owns="{{selectionId}}"/>
......
This files describes API changes in /theme/* themes,
information provided here is intended especially for theme designer.
=== 3.7 ===
* The core/form_autocompelte_input template now has a `data-tags` attribute.
=== 3.6 ===
* A new callback has been added to the theme layout files allowing plugins to inject their content
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment