Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add <select> support. Added unit tests and tested manually in Chrome, Sa... #25

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/autofill-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
// form fields a little later...
window.setTimeout(function() {
findParentForm(target).find('input').checkAndTriggerAutoFillEvent();
findParentForm(target).find('select').checkAndTriggerAutoFillEvent();
}, 20);
});

Expand Down Expand Up @@ -66,6 +67,18 @@
// ...
// Note: it's important to not use the value property here!
el.$$currentValue = el.getAttribute('value');

// This handles select elements, which have option tags as children
// If an option tag has the selected attribute, then it is the default
// value of the select element. Input elements don't have children,
// so it is safe to have this code run after the above statement.
if (el.children.length > 0) {
forEach(el.children, function(child) {
if (child.getAttribute("selected")) {
el.$$currentValue = child.getAttribute("value");
}
});
}
}

var val = el.value,
Expand Down
8 changes: 5 additions & 3 deletions test/manual/web-form.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ <h1>Prepare <button class="prepare-done">Done</button></h1>
</li>
<li>Click on "Manage Autofill settings"</li>
<li>Add a new street address with:
First Name="Some" / Last Name="User" / Address line 1="1234 Some Street" / City="Some City"
First Name="Some" / Last Name="User" / Address line 1="1234 Some Street" / City="Some City" / State="Oblivion"
</li>
</ol>

Expand All @@ -36,7 +36,7 @@ <h1>Prepare <button class="prepare-done">Done</button></h1>
Close preferences.
</li>
<li>
Enter name="Some User" / address="1234 Some Street" / City="Some City" and hit submit
Enter name="Some User" / address="1234 Some Street" / City="Some City" / State="Oblivion" and hit submit
</li>
<li>
The next page should show the values in json format
Expand All @@ -49,7 +49,7 @@ <h1>Prepare <button class="prepare-done">Done</button></h1>
Other browsers
<ol>
<li>
Enter name="Some User" / address="1234 Some Street" / City="Some City" and hit submit
Enter name="Some User" / address="1234 Some Street" / City="Some City" / State="Oblivion" and hit submit
</li>
<li>
The next page should show the values in json format
Expand All @@ -73,6 +73,7 @@ <h1>Form</h1>
Name: <input type="text" name="name" class="name" ng-model="name"><br>
Address: <input type="text" name="address" class="address" ng-model="address"><br>
City: <input type="text" name="city" class="city" ng-model="city"><br>
State: <select name="state" class="state" ng-model="state"><option></option><option value="Oblivion">Oblivion</option></select><br>
<button>Submit</button>
</form>

Expand All @@ -81,6 +82,7 @@ <h1>Form</h1>
Name: <span class="ng-name" ng-bind="name"></span><br>
Address: <span class="ng-address" ng-bind="address"></span><br>
City: <span class="ng-city" ng-bind="city"></span><br>
State: <span class="ng-state" ng-bind="state"></span><br>
</div>
</div>

Expand Down
17 changes: 13 additions & 4 deletions test/manual/web-formSpec.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
describe('normal forms', function() {
var name, address, city, ngName, ngAddress, ngCity,
var name, address, city, state, ngName, ngAddress, ngCity, ngState,
mt = window.manualTest;

var nameValue = 'Some User',
addressValue = '1234 Some Street',
cityValue = 'Some City';

cityValue = 'Some City',
stateValue = 'Oblivion';

beforeEach(function () {
name = document.querySelector('.name');
address = document.querySelector('.address');
city = document.querySelector('.city');
state = document.querySelector('.state');

ngName = document.querySelector('.ng-name');
ngAddress = document.querySelector('.ng-address');
ngCity = document.querySelector('.ng-city');
ngState = document.querySelector('.ng-state');
});

beforeEach(function() {
mt.askForInput(name, '', 'user field');
mt.askForInput(address, '', 'address field');
mt.askForInput(city, '', 'city field');
mt.askForInput(state, '', 'state field');
mt.askToBlur(name, 'name field');
mt.askToBlur(address, 'address field');
mt.askToBlur(city, 'city field');
mt.askToBlur(state, 'state field');
waitForAutoFill();
});

Expand Down Expand Up @@ -50,9 +56,12 @@ describe('normal forms', function() {
expect(name.value).toBe(nameValue);
expect(address.value).toBe(addressValue);
expect(city.value).toBe(cityValue);
expect(state.value).toBe(stateValue);

expect(ngName.textContent).toBe(nameValue);
expect(ngAddress.textContent).toBe(addressValue);
expect(ngCity.textContent).toBe(cityValue);
expect(ngState.textContent).toBe(stateValue);
});
});

Expand Down
116 changes: 112 additions & 4 deletions test/unit/autofill-eventSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('check other inputs when one input fires a blur event', function() {
container.remove()
});

it('should check elements in the same form and not in other forms after 20ms when an element is blurred', function() {
it('should check input elements in the same form and not in other forms after 20ms when an element is blurred', function() {
jasmine.Clock.useMock();

var spy = spyOn(testutils.$.prototype, 'checkAndTriggerAutoFillEvent');
Expand All @@ -28,9 +28,33 @@ describe('check other inputs when one input fires a blur event', function() {
jasmine.Clock.tick(20);

expect(spy).toHaveBeenCalled();
expect(spy.mostRecentCall.object.length).toBe(2);
expect(spy.mostRecentCall.object[0]).toBe(inputs[0]);
expect(spy.mostRecentCall.object[1]).toBe(inputs[1]);
expect(spy.calls[0].object.length).toBe(2);
expect(spy.calls[0].object[0]).toBe(inputs[0]);
expect(spy.calls[0].object[1]).toBe(inputs[1]);
});

it('should check select elements in the same form and not in other forms after 20ms when an element is blurred', function() {
jasmine.Clock.useMock();

var spy = spyOn(testutils.$.prototype, 'checkAndTriggerAutoFillEvent');

container.append("<form>" +
"<select id='sel1'><option value='1'>1</option><option value='2'>2</option></select>" +
"<select id='sel2'><option value='3'>3</option><option value='4'>4</option></select>" +
"</form><form>" +
"<select id='sel3'><option value='5'>5</option></select>" +
"</form>");
var selects = container.find('select');

testutils.triggerBlurEvent(selects[0]);
expect(spy).not.toHaveBeenCalled();

jasmine.Clock.tick(20);

expect(spy).toHaveBeenCalled();
expect(spy.calls[1].object.length).toBe(2);
expect(spy.calls[1].object[0]).toBe(selects[0]);
expect(spy.calls[1].object[1]).toBe(selects[1]);
});

describe('checkAndTriggerAutoFillEvent', function() {
Expand Down Expand Up @@ -120,4 +144,88 @@ describe('check other inputs when one input fires a blur event', function() {

});


describe('checkAndTriggerAutoFillEvent with selects', function() {
var select;

beforeEach(function() {
container.append('<select><option></option><option value="someValue">test value</option></select>');
select = container.children().eq(0);
});


describe('changes by user via change event', function() {
it('should not fire an extra change event when there was a change event for the element', function() {
// Don't use .val as we intercept this!
select[0].value = 'someValue';

testutils.triggerChangeEvent(select[0]);
expect(select[0].changeEventCount).toBe(1);

select.checkAndTriggerAutoFillEvent();

expect(select[0].changeEventCount).toBe(1);
});

it('should not fire an extra change event when the value did not change', function() {
// Don't use .val as we intercept this!
select[0].value = 'someValue';

testutils.triggerChangeEvent(select[0]);
select.checkAndTriggerAutoFillEvent();

testutils.triggerChangeEvent(select[0]);
select.checkAndTriggerAutoFillEvent();

expect(select[0].changeEventCount).toBe(2);
});
});

describe('changes by js code via $.fn.val', function() {
it('should not fire a change event when js code changes the element', function() {
select.val('someValue');
expect(select[0].changeEventCount).toBeUndefined();

select.checkAndTriggerAutoFillEvent();

expect(select[0].changeEventCount).toBeUndefined();
});

it('should not fire an extra change event when the value did not change', function() {
select.val('someValue');
select.checkAndTriggerAutoFillEvent();

select.val('someValue');
select.checkAndTriggerAutoFillEvent();

expect(select[0].changeEventCount).toBeUndefined();
});
});

describe('misc', function() {
it('should not fire for untouched select with empty value', function() {
select.checkAndTriggerAutoFillEvent();
expect(select[0].changeEventCount).toBeUndefined();
});

it('should not fire if select boxes are added with predefined value', function() {
container.append('<select><option value="someValue" selected="selected">test value</option></select>');
var newSelect = container.children().eq(1);
newSelect.checkAndTriggerAutoFillEvent();
expect(newSelect[0].changeEventCount).toBeUndefined();
});
});

it('should fire a change event if the value was changed by another way', function() {
// Don't use .val as we intercept this!
select[0].value = 'someValue';

select.checkAndTriggerAutoFillEvent();

expect(select[0].changeEventCount).toBe(1);
});

});


});