Files
ionic-framework/packages/angular/test/base/e2e/src/form.spec.ts
Sean Perkins 77707b8c1e fix(angular): min/max validator for ion-input type number (#27993)
Issue number: Resolves #23480

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

Angular's min/max validators do not work with `ion-input[type=number]`.
Using the built-in validators with `ion-input` will not update the
control status to invalid, reflect the `ng-invalid` class or report the
correct errors.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- The `IonicModule` now includes two additional directive declarations
that extend Angular's built-in min/max validators and target the
`ion-input` component when using `type="number"`.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this introduces a breaking change, please describe the impact
and migration path for existing applications below. -->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->
2023-08-18 18:34:02 +00:00

167 lines
4.1 KiB
TypeScript

describe('Form', () => {
beforeEach(() => {
cy.visit('/form');
})
describe('status updates', () => {
it('should update Ionic form classes when calling form methods programmatically', async () => {
cy.get('#input-touched').click();
cy.get('#touched-input-test').should('have.class', 'ion-touched');
});
describe('markAllAsTouched', () => {
it('should apply .ion-touched to nearest ion-item', () => {
cy.get('#mark-all-touched-button').click();
cy.get('form ion-item').each(item => {
cy.wrap(item).should('have.class', 'ion-touched');
});
});
});
});
describe('change', () => {
it('should have default values', () => {
testStatus('INVALID');
cy.get('#submit').should('have.text', 'false');
testData({
datetime: '2010-08-20',
select: null,
toggle: false,
input: '',
input2: 'Default Value',
inputMin: 1,
inputMax: 1,
checkbox: false
});
});
it('should become valid', () => {
cy.get('ion-input.required').type('Some value');
cy.get('ion-input.required input').blur();
testStatus('INVALID');
cy.get('ion-select').click();
cy.get('ion-alert').should('exist').should('be.visible');
// NES option
cy.get('ion-alert .alert-radio-button:nth-of-type(2)').click();
// Click confirm button
cy.get('ion-alert .alert-button:not(.alert-button-role-cancel)').click();
testStatus('VALID');
testData({
datetime: '2010-08-20',
select: 'nes',
toggle: false,
input: 'Some value',
input2: 'Default Value',
inputMin: 1,
inputMax: 1,
checkbox: false
});
});
it('ion-toggle should change', () => {
cy.get('form ion-toggle').click();
testData({
datetime: '2010-08-20',
select: null,
toggle: true,
input: '',
input2: 'Default Value',
inputMin: 1,
inputMax: 1,
checkbox: false
});
});
it('ion-checkbox should change', () => {
cy.get('ion-checkbox').click();
testData({
datetime: '2010-08-20',
select: null,
toggle: false,
input: '',
input2: 'Default Value',
inputMin: 1,
inputMax: 1,
checkbox: true
});
});
it('should submit', () => {
cy.get('#set-values').click();
cy.get('#submit-button').click();
cy.get('#submit').should('have.text', 'true');
});
});
describe('blur', () => {
it('ion-toggle should change only after blur', () => {
cy.get('form ion-toggle').click();
testData({
datetime: '2010-08-20',
select: null,
toggle: true,
input: '',
input2: 'Default Value',
inputMin: 1,
inputMax: 1,
checkbox: false
});
cy.get('ion-checkbox').click();
testData({
datetime: '2010-08-20',
select: null,
toggle: true,
input: '',
input2: 'Default Value',
inputMin: 1,
inputMax: 1,
checkbox: true
});
});
});
describe('validators', () => {
it('ion-input should error with min set', () => {
const control = cy.get('form ion-input[formControlName="inputMin"]');
control.should('have.class', 'ng-valid');
control.type('{backspace}0');
control.within(() => cy.get('input').blur());
control.should('have.class', 'ng-invalid');
});
it('ion-input should error with max set', () => {
const control = cy.get('form ion-input[formControlName="inputMax"]');
control.should('have.class', 'ng-valid');
control.type('2');
control.within(() => cy.get('input').blur());
control.should('have.class', 'ng-invalid');
});
});
});
function testStatus(status) {
cy.get('#status').should('have.text', status);
}
function testData(data) {
cy.get('#data').invoke('text').then(text => {
const value = JSON.parse(text);
console.log(value, data);
expect(value).to.deep.equal(data);
})
}