Skip to content

Commit

Permalink
Feature/smart input type (#3)
Browse files Browse the repository at this point in the history
* feat(smart-input-type): Add smart-input-type directive

- Implemented SmartInputType directive to enhance native input fields with custom validation options.
- Supported input types include alphanumeric, numeric, alpha, email, url, tel, and custom patterns.
- Added language-specific character filtering and case transformation features.
- Implemented debouncing for performance optimization during rapid input changes.
- Created README file detailing usage instructions, input options, and examples for the SmartInputType directive.

* refactor(smart-input-type): Update peer dependencies and tsconfig.lib.prod.json

Update the peer dependencies in the package.json file of the smart-input-type library to support Angular versions 17.0.0 and above. Also, modify the tsconfig.lib.prod.json file to set the compilation mode to "partial".

* test(smart-input-type): add comprehensive unit test suite for SmartInputTypeDirective

- Add test cases for alphanumeric, alpha, numeric, email, url, and tel input validation
- Include support for custom patterns, case transformations (uppercase/lowercase), and space handling
- Test language set filtering for English, Spanish, and French
- Add debouncing test with configurable debounceTime
- Ensure form control error handling for invalid inputs (strictEmail, strictUrl, strictTel)
- Add tests for visual feedback, handling of long strings, and special characters
- Ensure proper functionality with password input types and invalid HTML input types

* refactor(smart-input-type): Update language map for smart input types

* feat(smart-input-type-demo): create demo application with comprehensive unit tests

- Implement Smart Input Type Demo application showcasing various input types and validation features.
- Add unit test cases for input transformations, validations, and error handling.
- Ensure coverage for alphanumeric, numeric, email, URL, and custom pattern inputs.
- Include visual feedback for errors and debouncing functionality.

* refactor(package.json): Update build and lint scripts

- Update the build script to include the "smart-input-type" target
- Update the lint script to include the "smart-input-type" target

* test(e2e): add Cypress end-to-end tests for Smart Input Type Demo

- Implement end-to-end tests for the Smart Input Type Demo application.
- Cover input validation scenarios, including email, URL, and telephone formats.
- Validate transformation and restrictions for various input types.
- Ensure visual feedback for error handling is properly tested.
- Include tests for alphanumeric, numeric, and custom pattern inputs.

* docs: update README to add smart-input-type library

* docs: update demo link in README.md

* refactor(package.json): Update smart-input-type version and add description, author, license, repository, and keywords
  • Loading branch information
AditechGH authored Oct 8, 2024
1 parent 9cbc129 commit 0592cbd
Show file tree
Hide file tree
Showing 26 changed files with 1,671 additions and 47 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ngx-smart-forms is a collection of Angular libraries designed to enhance form ha

- [About the Project](#about-the-project)
- [Libraries](#libraries)
- [@ngx-smart-forms/smart-input-type](#ngx-smart-formssmart-error-display)
- [@ngx-smart-forms/smart-error-display](#ngx-smart-formssmart-error-display)
- [Getting Started](#getting-started)
- [Installation](#installation)
Expand All @@ -27,6 +28,18 @@ The main goal of this project is to deliver reusable and easily customizable for

## Libraries

### @ngx-smart-forms/smart-input-type

The `@ngx-smart-forms/smart-input-type` is a powerful Angular directive that enhances native HTML input elements with advanced validation and formatting capabilities.

- Key Features:
- Enforces various input types and custom regex patterns.
- Integrates with native HTML input types and reactive forms.
- Supports case transformation and language-specific character sets.
- Provides clear error visibility through automatic CSS class application.

For more details, see the full [README](./libs/smart-input-type/README.md).

### @ngx-smart-forms/smart-error-display

The `@ngx-smart-forms/smart-error-display` is a robust Angular component for displaying form validation errors. It supports both reactive and template-driven forms, offering localization, theming, and custom error handling.
Expand Down
42 changes: 0 additions & 42 deletions apps/ngx-smart-forms-e2e/src/e2e/app.cy.ts
Original file line number Diff line number Diff line change
@@ -1,42 +0,0 @@
/* eslint-disable cypress/unsafe-to-chain-command */
describe('SmartErrorDisplayDemoComponent E2E', () => {
beforeEach(() => {
cy.visit('/smart-error-display-demo');
});

describe('Basic Form Validation', () => {
it('should remove error when username becomes valid', () => {
cy.get('input[formControlName="username"]').type('validUsername').blur();
cy.get('#usernameError').should('be.empty');
});
});

describe('Custom Error Messages', () => {
it('should display custom error message when username is too short', () => {
cy.get('input[formControlName="customUsername"]').type('ab').blur();
cy.get('#customUsernameError')
.should('be.visible')
.and('contain', 'Username must be at least 3 characters long.');
});
});

describe('Custom Error Formatter', () => {
it('should display custom error formatter message', () => {
cy.get('input[formControlName="customFormatterUsername"]')
.type('ab')
.blur();
cy.get('#customFormatterUsernameError')
.should('be.visible')
.and('contain', 'Minimum length is 5 characters.');
});
});

describe('Custom Error Display Control', () => {
it('should display error when email is invalid', () => {
cy.get('input[formControlName="edcEmail"]').type('invalidEmail').blur();
cy.get('#edcEmailError')
.should('be.visible')
.and('contain', 'Please enter a valid email address.');
});
});
});
42 changes: 42 additions & 0 deletions apps/ngx-smart-forms-e2e/src/e2e/smart-error-display-demo.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* eslint-disable cypress/unsafe-to-chain-command */
describe('SmartErrorDisplayDemoComponent E2E', () => {
beforeEach(() => {
cy.visit('/smart-error-display-demo');
});

describe('Basic Form Validation', () => {
it('should remove error when username becomes valid', () => {
cy.get('input[formControlName="username"]').type('validUsername').blur();
cy.get('#usernameError').should('be.empty');
});
});

describe('Custom Error Messages', () => {
it('should display custom error message when username is too short', () => {
cy.get('input[formControlName="customUsername"]').type('ab').blur();
cy.get('#customUsernameError')
.should('be.visible')
.and('contain', 'Username must be at least 3 characters long.');
});
});

describe('Custom Error Formatter', () => {
it('should display custom error formatter message', () => {
cy.get('input[formControlName="customFormatterUsername"]')
.type('ab')
.blur();
cy.get('#customFormatterUsernameError')
.should('be.visible')
.and('contain', 'Minimum length is 5 characters.');
});
});

describe('Custom Error Display Control', () => {
it('should display error when email is invalid', () => {
cy.get('input[formControlName="edcEmail"]').type('invalidEmail').blur();
cy.get('#edcEmailError')
.should('be.visible')
.and('contain', 'Please enter a valid email address.');
});
});
});
136 changes: 136 additions & 0 deletions apps/ngx-smart-forms-e2e/src/e2e/smart-input-type-demo.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/* eslint-disable cypress/no-unnecessary-waiting */
/* eslint-disable cypress/unsafe-to-chain-command */
describe('Smart Input Type Demo - E2E Tests', () => {
beforeEach(() => {
// Visit the SmartInputDemo page
cy.visit('/smart-input-type-demo'); // Replace with the actual URL or path
});

it('should create the SmartInputDemoComponent', () => {
// Check if the demo component is visible
cy.get('h2').contains('Smart Input Type Demo').should('be.visible');
});

describe('Enhanced Input Validation and Formatting', () => {
it('should transform alphanumeric input (no spaces)', () => {
cy.get('#alphanumeric-no-spaces')
.type('Test 123!@#')
.should('have.value', 'Test123');
});

it('should allow alphanumeric input with spaces', () => {
cy.get('#alphanumeric-with-spaces')
.type('Test 123!@#')
.should('have.value', 'Test 123');
});

it('should validate numeric input without spaces', () => {
cy.get('#numeric-no-spaces').type('123abc').should('have.value', '123');
});

it('should allow numeric input with spaces', () => {
cy.get('#numeric-with-spaces')
.type('123 abc')
.should('have.value', '123 ');
});

it('should transform alpha input (no spaces)', () => {
cy.get('#alpha-no-spaces').type('Test123').should('have.value', 'Test');
});

it('should allow alpha input with spaces', () => {
cy.get('#alpha-with-spaces')
.type('Test 123')
.should('have.value', 'Test ');
});

it('should validate input based on custom pattern', () => {
cy.get('#custom-pattern').type('123abc').should('have.value', '123');
});

it('should handle language-specific input (Spanish)', () => {
cy.get('#language-specific-input')
.type('testéñ123')
.should('have.value', 'testéñ123');
});

it('should handle language-specific input (Arabic numerals)', () => {
cy.get('#arabic-numerals').type('123٤٥٦abc').should('have.value', '٤٥٦');
});

it('should transform input to uppercase', () => {
cy.get('#case-sensitive-input')
.type('test123')
.should('have.value', 'TEST123');
});

it('should work with password input type', () => {
cy.get('#password').should('have.attr', 'type', 'password');
});

it('should debounce input validation', () => {
cy.get('#debounce-input')
.type('Test123')
.wait(500) // Debounce time
.should('have.value', 'Test123');
});

it('should handle language set with case transformation', () => {
cy.get('#language-set-case-sensitivity')
.type('tëst123')
.should('have.value', 'tëst123');
});

it('should add .has-error class for invalid email input', () => {
cy.get('#visual-feedback-input')
.type('invalidEmail')
.blur() // Simulate blur to trigger validation
.should('have.class', 'has-error');
});

it('should not have .has-error class for valid email input', () => {
cy.get('#visual-feedback-input')
.clear()
.type('[email protected]')
.blur()
.should('not.have.class', 'has-error');
});
});

describe('Enhanced Form Validation', () => {
it('should show error for invalid email', () => {
cy.get('#email').type('invalidEmail').blur();

cy.get('#email + div')
.should('be.visible')
.and('contain.text', 'Invalid Email');
});

it('should show error for invalid URL', () => {
cy.get('#url').type('invalid-url').blur();

cy.get('#url + div')
.should('be.visible')
.and('contain.text', 'Invalid URL format');
});

it('should show error for invalid phone number', () => {
cy.get('#tel').type('abc123').blur();

cy.get('#tel + div')
.should('be.visible')
.and('contain.text', 'Invalid phone number');
});

it('should not show errors for valid form inputs', () => {
cy.get('#email').clear().type('[email protected]').blur();
cy.get('#email + div').should('not.exist');

cy.get('#url').clear().type('https://example.com').blur();
cy.get('#url + div').should('not.exist');

cy.get('#tel').clear().type('1234567890').blur();
cy.get('#tel + div').should('not.exist');
});
});
});
2 changes: 0 additions & 2 deletions apps/ngx-smart-forms/src/app/app.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
<router-outlet></router-outlet>

Hello world!
6 changes: 6 additions & 0 deletions apps/ngx-smart-forms/src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Route } from '@angular/router';

import { SmartErrorDisplayDemoComponent } from './smart-error-display-demo/smart-error-display-demo.component';
import { SmartInputTypeDemoComponent } from './smart-input-type-demo/smart-input-type-demo.component';

export const appRoutes: Route[] = [
{
path: 'smart-error-display-demo',
component: SmartErrorDisplayDemoComponent,
},
{
path: 'smart-input-type-demo',
component: SmartInputTypeDemoComponent,
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
input.has-error {
border-color: red;
}
Loading

0 comments on commit 0592cbd

Please sign in to comment.