Skip to content

Commit

Permalink
fix(core): don't ignore native attribute maxlength (#350)
Browse files Browse the repository at this point in the history
  • Loading branch information
nsbarsukov authored Jun 29, 2023
1 parent 8fe9445 commit 8504f49
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 2 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ jobs:
- name: Run Cypress tests
# Replace with npm run cy:run -- --spec "**/!(kit|recipes)/*.cy.ts" --config baseUrl="${{ env.UNIVERSAL_SERVER }}"
# After this issue fix: https://github.com/cypress-io/cypress/issues/22407
run: npm run cy:run -- --spec "**/(angular|ssr)/**/*.cy.ts" --config baseUrl="${{ env.UNIVERSAL_SERVER }}"
run:
npm run cy:run -- --spec "**/(angular|ssr|others)/**/*.cy.ts" --config baseUrl="${{ env.UNIVERSAL_SERVER }}"

concurrency:
group: e2e-${{ github.workflow }}-${{ github.ref }}
Expand Down
10 changes: 10 additions & 0 deletions projects/core/src/lib/mask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ export class Maskito extends MaskHistory {
};
}

private get maxLength(): number {
const {maxLength} = this.element;

return maxLength === -1 ? Infinity : maxLength;
}

destroy(): void {
this.eventListener.destroy();
this.teardowns.forEach(teardown => teardown?.());
Expand Down Expand Up @@ -294,6 +300,10 @@ export class Maskito extends MaskHistory {
elementState.value.slice(0, from) + data + elementState.value.slice(to);
const newElementState = this.postprocessor(maskModel, initialElementState);

if (newElementState.value.length > this.maxLength) {
return event.preventDefault();
}

if (newPossibleValue !== newElementState.value) {
event.preventDefault();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {DemoPath} from '@demo/constants';

import {BROWSER_SUPPORTS_REAL_EVENTS} from '../../support/constants';

describe('Native attribute maxlength works', () => {
describe('<input maxlength="3" /> & overwriteMode = shift', () => {
beforeEach(() => {
cy.visit(DemoPath.Cypress);
cy.get('#maxlength input[maxlength="3"]')
.should('have.prop', 'maxlength', 3)
.as('input');
});

it('accepts 2 digits', () => {
cy.get('@input').type('12').should('have.value', '12');
});

it('accepts 3 digits', () => {
cy.get('@input').type('123').should('have.value', '123');
});

it(
'can replace selected digit by new one (even if length of the value is already equal to maxlength-property)',
BROWSER_SUPPORTS_REAL_EVENTS,
() => {
cy.get('@input').type('123').realPress(['Shift', 'ArrowLeft']);

cy.get('@input').type('0').should('have.value', '120');
},
);

describe('rejects to enter digits more than maxlength-property', () => {
it('123| => Type 4 => 123|', () => {
cy.get('@input')
.type('1234')
.should('have.value', '123')
.should('have.prop', 'selectionStart', '123'.length)
.should('have.prop', 'selectionEnd', '123'.length);
});

it('12|3 => Type 0 => 12|3', () => {
cy.get('@input')
.type('123')
.type('{leftArrow}')
.type('0')
.should('have.value', '123')
.should('have.prop', 'selectionStart', '12'.length)
.should('have.prop', 'selectionEnd', '12'.length);
});

it('1|23 => Type 0 => 1|23', () => {
cy.get('@input')
.type('123')
.type('{leftArrow}'.repeat(2))
.type('0')
.should('have.value', '123')
.should('have.prop', 'selectionStart', 1)
.should('have.prop', 'selectionEnd', 1);
});

it('|123 => Type 9 => |123', () => {
cy.get('@input')
.type('123')
.type('{moveToStart}')
.type('9')
.should('have.value', '123')
.should('have.prop', 'selectionStart', 0)
.should('have.prop', 'selectionEnd', 0);
});
});
});

describe('<input maxlength="6" /> & overwriteMode = replace', () => {
beforeEach(() => {
cy.visit(DemoPath.Cypress);
cy.get('#maxlength input[maxlength="6"]')
.should('have.prop', 'maxlength', 6)
.as('input');
});

it('accepts valid 526ed3', () => {
cy.get('@input').type('526ed3').should('have.value', '526ED3');
});

describe('does not allow to type characters more than [maxlength]', () => {
it('many letters', () => {
cy.get('@input')
.type('aaabbbcccdddeeefff')
.should('have.value', 'AAABBB');
});

it('many digits', () => {
cy.get('@input').type('1234567890').should('have.value', '123456');
});
});

it("overwriteMode 'replace' works even if value's length is equal to [maxlength]", () => {
cy.get('@input')
.type('123456')
.type('{leftArrow}'.repeat(3))
.type('09')
.should('have.value', '123096');
});
});
});
1 change: 1 addition & 0 deletions projects/demo/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ export const appRoutes: Routes = [
title: `Stackblitz Starter`,
},
},
// TODO: replace this page with Cypress Component Testing after angular13+ update
{
path: DemoPath.Cypress,
loadChildren: async () =>
Expand Down
3 changes: 2 additions & 1 deletion projects/demo/src/pages/cypress/cypress.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {TuiInputModule} from '@taiga-ui/kit';

import {CypressDocPageComponent} from './cypress.component';
import {TestDocExample1} from './examples/1-predicate/component';
import {TestDocExample2} from './examples/2-native-max-length/component';

@NgModule({
imports: [
Expand All @@ -20,7 +21,7 @@ import {TestDocExample1} from './examples/1-predicate/component';
TuiAddonDocModule,
RouterModule.forChild(tuiGenerateRoutes(CypressDocPageComponent)),
],
declarations: [CypressDocPageComponent, TestDocExample1],
declarations: [CypressDocPageComponent, TestDocExample1, TestDocExample2],
exports: [CypressDocPageComponent],
})
export class CypressDocPageModule {}
2 changes: 2 additions & 0 deletions projects/demo/src/pages/cypress/cypress.template.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<tui-doc-page header="Cypress">
<ng-template pageTab="Tests">
<test-doc-example-1 id="predicate"></test-doc-example-1>

<test-doc-example-2 id="maxlength"></test-doc-example-2>
</ng-template>
</tui-doc-page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {MaskitoOptions} from '@maskito/core';
import {maskitoNumberOptionsGenerator} from '@maskito/kit';

@Component({
selector: 'test-doc-example-2',
template: `
<input
maxlength="3"
[maskito]="numberMask"
/>
<input
maxlength="6"
[maskito]="hexColorMask"
/>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TestDocExample2 {
readonly numberMask = maskitoNumberOptionsGenerator({
thousandSeparator: ' ',
});

readonly hexColorMask: MaskitoOptions = {
mask: /^[A-F\d]*$/gi,
overwriteMode: 'replace',
postprocessors: [
({value, selection}) => ({
selection,
value: value.toUpperCase(),
}),
],
};
}

0 comments on commit 8504f49

Please sign in to comment.