-
Notifications
You must be signed in to change notification settings - Fork 27.5k
angular.element.val() and jquery.val() should call $setViewValue() when necessary #6523
Comments
giving this a quick read, this doesn't seem like the right solution --- jQuery should not have any special connection to ngModel |
@caitp: It wouldn't be "connected", at all. The idea would be to wrap the call and simply make sure $setViewValue was called afterwards if need be. Currently, if you programmatically update the value of an input, tied to a model, it will not trigger validation. Programmatically updating the input is the only way to e2e test HTML5 inputs like "date" with Protractor. Needless to say, as time passes, this need will be more and more frequent. The proposed solution will make this: var script = "var input = document.getElementById('someInput');" +
"input.value = '2011-11-11';" +
"angular.element(input).scope().$apply(function(s) { s[input[0].form.name][input.name].$setViewValue('2011-11-11');";
browser.executeScript(script); into browser.executeScript("angular.element(document.getElementById('someInput')).val('2011-11-11')"); |
I'm always open to a custom protractor helper that does all of the above as well, but that seems wonky.... and even so, Protractor could benefit from this functionality. |
I don't think this is right, but your PRs have been reviewed by @tbosch I think, so maybe he could look at this suggestion and see what he thinks |
lol... Which "this"? If I'm totally honest, I'm not entirely sure this is the best solution... I'm only sure of three things:
It won't hurt my feelings if my proposed solution is rejected, at all. Just as long as there is some sort of identified fix to the issue at hand, which is testing HTML5 controls with protractor and making sure Angular validates it is a real pain. |
Argh... I said Protractor wasn't an Angular specific tool above and that's completely false... I'm an "Angular specific tool". I'm tired... Maybe the solution is a helper in Protractor? @juliemr may be a helpful resource here. |
I do not think that making any change to jqLite.val or jQuery.val is the right way as it is sometimes needed to have full control on when a value is changed and an event is triggered. We do not use Protractor, anyhow we do use a helper function that does this.isVisible = function (selector) {
return !$rootElement.find(selector).hasClass('ng-hide');
};
this.editText = function (selector, text) {
var element = $rootElement.find(selector);
expect(this.isVisible(selector)).toBe(true);
element.val(text);
browserTrigger(element, $sniffer.hasEvent('input') ? 'input' : 'change');
}
[...]
function browserTrigger(element, eventType) {
'use strict';
element = element[0];
if (window.document.createEvent) {
var event = window.document.createEvent('MouseEvents');
event.initMouseEvent(eventType, true, true, window, 0, 0, 0, 0, 0, false, false,
false, false, 0, element);
element.dispatchEvent(event);
} else {
if ((element.type === "checkbox" || element.type === "radio") && element.click) {
element.click();
} else {
element.fireEvent('on' + eventType);
}
}
} |
I think the right solution would have a temporary fix in protractor until webdriver supports this correctly. Protractor can monkey patch jQuery Lite / provide a new method there to do what is needed. So solving angular/protractor#562 would be the right thing to do. |
Can we close this here then? |
This issue stems from trying to e2e test HTML5 inputs with protractor.
Problem
WebDriver/Selenium is unable to "sendkeys" to all browsers' implementations of HTML5 controls such as date, time, datetime-local, color, etc. Consequently, these things are hard to test.
Current workaround
Currently in order to set the value of the element with Protractor you need to use
browser.executeScript()
. For example:This does the work of setting the value of the input, however, the way Angular is wiring up validation, the validation will not be fired. This means you also have to manually call
$setViewValue()
on the model:... which is, of course, ugly as sin.
Proposed solution
It seems to make sense to have
angular.element.val()
check to see if the input is part of a form that has a model and force the validation. Likewise, if JQuery is being used, theval()
extension could be wrapped to support this behavior. Of courseval()
should perform as expected on any other input that doesn't have a model bound to it.Related
angular/protractor#562
#5864
The text was updated successfully, but these errors were encountered: