Skip to content

Commit 9181501

Browse files
crisbetostephenrca
authored andcommitted
fix(cdk/testing): sending incorrect keyCode for comma (angular#27472)
Fixes that the `TestElement.sendKeys` was triggering a keyboard event with the wrong `keyCode` for commas, because a comma has a different `keyCode` than its `charCode`.
1 parent 992efcc commit 9181501

File tree

6 files changed

+43
-4
lines changed

6 files changed

+43
-4
lines changed

src/cdk/testing/testbed/fake-events/type-in-element.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {getNoKeysSpecifiedError, ModifierKeys} from '@angular/cdk/testing';
10-
import {PERIOD} from '@angular/cdk/keycodes';
10+
import {COMMA, PERIOD} from '@angular/cdk/keycodes';
1111
import {dispatchFakeEvent, dispatchKeyboardEvent} from './dispatch-events';
1212
import {triggerFocus} from './element-focus';
1313

@@ -22,6 +22,11 @@ const incrementalInputTypes = new Set([
2222
'url',
2323
]);
2424

25+
/** Characters whose key code doesn't match their character code. */
26+
const KEYCODE_MISMATCHES: Record<string, number> = {
27+
',': COMMA,
28+
};
29+
2530
/**
2631
* Checks whether the given Element is a text input element.
2732
* @docs-private
@@ -78,7 +83,12 @@ export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any[])
7883
const keys: {keyCode?: number; key?: string}[] = rest
7984
.map(k =>
8085
typeof k === 'string'
81-
? k.split('').map(c => ({keyCode: c.toUpperCase().charCodeAt(0), key: c}))
86+
? k.split('').map(c => ({
87+
keyCode: KEYCODE_MISMATCHES.hasOwnProperty(c)
88+
? KEYCODE_MISMATCHES[c]
89+
: c.toUpperCase().charCodeAt(0),
90+
key: c,
91+
}))
8292
: [k],
8393
)
8494
.reduce((arr, k) => arr.concat(k), []);

src/cdk/testing/tests/cross-environment.spec.ts

+6
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ export function crossEnvironmentSpecs(
209209
expect(await specialKey.text()).toBe('enter');
210210
});
211211

212+
it('should send comma key', async () => {
213+
const specialKey = await harness.specaialKey();
214+
await harness.sendComma();
215+
expect(await specialKey.text()).toBe(',');
216+
});
217+
212218
it('should send alt+j key', async () => {
213219
const specialKey = await harness.specaialKey();
214220
await harness.sendAltJ();

src/cdk/testing/tests/harnesses/main-component-harness.ts

+4
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ export class MainComponentHarness extends ComponentHarness {
152152
return (await this.input()).sendKeys({alt: true}, 'j');
153153
}
154154

155+
async sendComma(): Promise<void> {
156+
return (await this.input()).sendKeys(',');
157+
}
158+
155159
async getTaskStateResult(): Promise<string> {
156160
await (await this.taskStateTestTrigger()).click();
157161
// Wait for async tasks to complete since the click caused a

src/cdk/testing/tests/test-main-component.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ENTER} from '@angular/cdk/keycodes';
9+
import {COMMA, ENTER} from '@angular/cdk/keycodes';
1010
import {_supportsShadowDom} from '@angular/cdk/platform';
1111
import {FormControl} from '@angular/forms';
1212
import {
@@ -91,6 +91,9 @@ export class TestMainComponent implements OnDestroy {
9191
if (event.key === 'j' && event.altKey) {
9292
this.specialKey = 'alt-j';
9393
}
94+
if (event.keyCode === COMMA && event.key === ',') {
95+
this.specialKey = ',';
96+
}
9497
}
9598

9699
onClick(event: MouseEvent) {

src/material/chips/testing/BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ ng_test_library(
1919
srcs = glob(["**/*.spec.ts"]),
2020
deps = [
2121
":testing",
22+
"//src/cdk/keycodes",
2223
"//src/cdk/testing",
2324
"//src/cdk/testing/testbed",
2425
"//src/material/chips",

src/material/chips/testing/chip-input-harness.spec.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {HarnessLoader} from '@angular/cdk/testing';
2+
import {COMMA} from '@angular/cdk/keycodes';
23
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
34
import {Component} from '@angular/core';
45
import {ComponentFixture, TestBed} from '@angular/core/testing';
@@ -69,12 +70,24 @@ describe('MatChipInputHarness', () => {
6970
await harness.blur();
7071
expect(await harness.isFocused()).toBe(false);
7172
});
73+
74+
it('should be able to trigger a separator key', async () => {
75+
const input = await loader.getHarness(MatChipInputHarness);
76+
await input.setValue('Hello');
77+
await input.sendSeparatorKey(',');
78+
expect(fixture.componentInstance.add).toHaveBeenCalled();
79+
});
7280
});
7381

7482
@Component({
7583
template: `
7684
<mat-chip-grid #grid1>
77-
<input [matChipInputFor]="grid1" [required]="required" placeholder="Placeholder" />
85+
<input
86+
[matChipInputFor]="grid1"
87+
[required]="required"
88+
placeholder="Placeholder"
89+
(matChipInputTokenEnd)="add()"
90+
[matChipInputSeparatorKeyCodes]="separatorKeyCodes"/>
7891
</mat-chip-grid>
7992
8093
<mat-chip-grid #grid2>
@@ -84,4 +97,6 @@ describe('MatChipInputHarness', () => {
8497
})
8598
class ChipInputHarnessTest {
8699
required = false;
100+
add = jasmine.createSpy('add spy');
101+
separatorKeyCodes = [COMMA];
87102
}

0 commit comments

Comments
 (0)