mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
test: test input masking
This commit is contained in:
@@ -374,6 +374,14 @@ export class Input implements ComponentInterface {
|
||||
this.emitStyle();
|
||||
}
|
||||
|
||||
@Watch('mask')
|
||||
protected maskChanged() {
|
||||
if (this.maskController) {
|
||||
this.maskController.destroy();
|
||||
}
|
||||
this.initInputMask();
|
||||
}
|
||||
|
||||
componentWillLoad() {
|
||||
const { el } = this;
|
||||
|
||||
@@ -400,18 +408,9 @@ export class Input implements ComponentInterface {
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
const { mask, nativeInput } = this;
|
||||
|
||||
this.originalIonInput = this.ionInput;
|
||||
|
||||
if (mask !== undefined && nativeInput) {
|
||||
const formattedMask = formatMask(mask);
|
||||
if (formattedMask) {
|
||||
this.maskController = new MaskController(nativeInput, {
|
||||
mask: formattedMask,
|
||||
});
|
||||
}
|
||||
}
|
||||
this.initInputMask();
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
@@ -484,6 +483,18 @@ export class Input implements ComponentInterface {
|
||||
return clearOnEdit === undefined ? type === 'password' : clearOnEdit;
|
||||
}
|
||||
|
||||
private initInputMask() {
|
||||
const { mask, nativeInput } = this;
|
||||
if (mask !== undefined && nativeInput) {
|
||||
const formattedMask = formatMask(mask);
|
||||
if (formattedMask) {
|
||||
this.maskController = new MaskController(nativeInput, {
|
||||
mask: formattedMask,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getValue(): string {
|
||||
return typeof this.value === 'number' ? this.value.toString() : (this.value || '').toString();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
grid-row-gap: 20px;
|
||||
grid-column-gap: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
@@ -27,6 +28,7 @@
|
||||
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
@@ -40,7 +42,7 @@
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Input - Item</ion-title>
|
||||
<ion-title>Input - Mask</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
@@ -51,6 +53,17 @@
|
||||
|
||||
<ion-input id="input-phone-us" label="Phone"></ion-input>
|
||||
</div>
|
||||
<div class="grid-item">
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-title>Dynamic Mask</ion-card-title>
|
||||
</ion-card-header>
|
||||
<ion-card-content>
|
||||
<ion-input id="dynamicMaskInput" label="Enter a mask"></ion-input>
|
||||
<ion-input id="dynamicExample" label="Example"></ion-input>
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
@@ -76,6 +89,22 @@
|
||||
/\d/,
|
||||
/\d/,
|
||||
];
|
||||
|
||||
inputPhoneUS.addEventListener('ionInput', (ev) => {
|
||||
console.log('** ionInput event **', ev.detail);
|
||||
});
|
||||
|
||||
inputPhoneUS.addEventListener('ionChange', (ev) => {
|
||||
console.log('** ionChange event **', ev.detail);
|
||||
});
|
||||
|
||||
const dynamicMaskInput = document.querySelector('#dynamicMaskInput');
|
||||
dynamicMaskInput.addEventListener('ionChange', (ev) => {
|
||||
const mask = ev.detail.value;
|
||||
const exampleInput = document.querySelector('#dynamicExample');
|
||||
console.log('setting the mask to: ', mask);
|
||||
exampleInput.mask = mask;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
44
core/src/components/input/test/mask/input.e2e.ts
Normal file
44
core/src/components/input/test/mask/input.e2e.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { configs } from '@utils/test/playwright';
|
||||
|
||||
import { test } from './mask-fixture';
|
||||
|
||||
configs({
|
||||
modes: ['md'],
|
||||
directions: ['ltr'],
|
||||
}).forEach(({ title, config }) => {
|
||||
test.describe(title('input: mask'), () => {
|
||||
test('should mask the input', async ({ maskPage }) => {
|
||||
// US Phone number
|
||||
await maskPage.init(config, [
|
||||
'+',
|
||||
'1',
|
||||
' ',
|
||||
'(',
|
||||
/\d/,
|
||||
/\d/,
|
||||
/\d/,
|
||||
')',
|
||||
' ',
|
||||
/\d/,
|
||||
/\d/,
|
||||
/\d/,
|
||||
'-',
|
||||
/\d/,
|
||||
/\d/,
|
||||
/\d/,
|
||||
/\d/,
|
||||
]);
|
||||
|
||||
await maskPage.typeAndBlur('5555555555');
|
||||
await maskPage.expectValue('+1 (555) 555-5555');
|
||||
});
|
||||
|
||||
test('should mask the input with a string', async ({ maskPage }) => {
|
||||
// Only allow lowercase letters
|
||||
await maskPage.init(config, '[a-z]$');
|
||||
|
||||
await maskPage.typeAndBlur('5abc123d');
|
||||
await maskPage.expectValue('abcd');
|
||||
});
|
||||
});
|
||||
});
|
||||
57
core/src/components/input/test/mask/mask-fixture.ts
Normal file
57
core/src/components/input/test/mask/mask-fixture.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import type { E2ELocator, E2EPage, TestConfig } from '@utils/test/playwright';
|
||||
import { test as base } from '@utils/test/playwright';
|
||||
import type { MaskExpression } from 'src/interface';
|
||||
|
||||
const stringifyMask = (mask: MaskExpression | string): string => {
|
||||
if (typeof mask === 'string') {
|
||||
return `'${mask}'`;
|
||||
}
|
||||
if (Array.isArray(mask)) {
|
||||
return `[${mask.map(stringifyMask).join(', ')}]`;
|
||||
}
|
||||
return mask.toString();
|
||||
};
|
||||
|
||||
class MaskPage {
|
||||
ionInput!: E2ELocator;
|
||||
nativeInput!: E2ELocator;
|
||||
|
||||
constructor(private page: E2EPage) {}
|
||||
|
||||
async init(config: TestConfig, mask: MaskExpression | string) {
|
||||
await this.page.setContent(
|
||||
`<ion-input></ion-input>
|
||||
<script>
|
||||
const input = document.querySelector('ion-input');
|
||||
input.mask = ${stringifyMask(mask)};
|
||||
</script>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
this.ionInput = this.page.locator('ion-input');
|
||||
this.nativeInput = this.page.locator('ion-input input');
|
||||
}
|
||||
|
||||
async typeAndBlur(value: string) {
|
||||
await this.ionInput.click();
|
||||
|
||||
await this.ionInput.type(value, { delay: 50 });
|
||||
await this.ionInput.blur();
|
||||
}
|
||||
|
||||
async expectValue(value: string) {
|
||||
expect(await this.ionInput.evaluate((node: HTMLIonInputElement) => node.value)).toBe(value);
|
||||
}
|
||||
}
|
||||
|
||||
type MaskFixtures = {
|
||||
maskPage: MaskPage;
|
||||
};
|
||||
|
||||
export const test = base.extend<MaskFixtures>({
|
||||
maskPage: async ({ page }, use) => {
|
||||
await use(new MaskPage(page));
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user