Skip to content

Commit 84ebadf

Browse files
committed
fix(cdk/testing): TestElement sendKeys method should not throw if no keys have been specified
Previously, calling `sendKeys` without any keys resulted in an error being thrown. This is because the first element of the passed arguments to `sendKeys` has been considered always truthy. This assumption is wrong since arbitrary amount of arguments can be passed due to the spread parameter. Also, calling `sendKeys` without any keys should not result in the element being focused. Pressing no keys/entering no text, does require the element to be focused.
1 parent 39dd216 commit 84ebadf

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

src/cdk/testing/protractor/protractor-element.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class ProtractorElement implements TestElement {
100100
const first = modifiersAndKeys[0];
101101
let modifiers: ModifierKeys;
102102
let rest: (string | TestKey)[];
103-
if (typeof first !== 'string' && typeof first !== 'number') {
103+
if (first !== undefined && typeof first !== 'string' && typeof first !== 'number') {
104104
modifiers = first;
105105
rest = modifiersAndKeys.slice(1);
106106
} else {
@@ -113,6 +113,12 @@ export class ProtractorElement implements TestElement {
113113
.reduce((arr, k) => arr.concat(k), [])
114114
.map(k => Key.chord(...modifierKeys, k));
115115

116+
// Do nothing if no keys have been specified. Calling this function with no keys should
117+
// not result in a focus event being dispatched.
118+
if (keys.length === 0) {
119+
return;
120+
}
121+
116122
return this.element.sendKeys(...keys);
117123
}
118124

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function isTextInput(element: Element): element is HTMLInputElement | HTM
2020
}
2121

2222
/**
23-
* Focuses an input, sets its value and dispatches
23+
* If keys have been specified, focuses an input, sets its value and dispatches
2424
* the `input` event, simulating the user typing.
2525
* @param element Element onto which to set the value.
2626
* @param keys The keys to send to the element.
@@ -30,7 +30,7 @@ export function typeInElement(
3030
element: HTMLElement, ...keys: (string | {keyCode?: number, key?: string})[]): void;
3131

3232
/**
33-
* Focuses an input, sets its value and dispatches
33+
* If keys have been specified, focuses an input, sets its value and dispatches
3434
* the `input` event, simulating the user typing.
3535
* @param element Element onto which to set the value.
3636
* @param modifiers Modifier keys that are held while typing.
@@ -40,11 +40,12 @@ export function typeInElement(
4040
export function typeInElement(element: HTMLElement, modifiers: ModifierKeys,
4141
...keys: (string | {keyCode?: number, key?: string})[]): void;
4242

43-
export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any) {
43+
export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any[]) {
4444
const first = modifiersAndKeys[0];
4545
let modifiers: ModifierKeys;
4646
let rest: (string | {keyCode?: number, key?: string})[];
47-
if (typeof first !== 'string' && first.keyCode === undefined && first.key === undefined) {
47+
if (first !== undefined && typeof first !== 'string' && first.keyCode === undefined &&
48+
first.key === undefined) {
4849
modifiers = first;
4950
rest = modifiersAndKeys.slice(1);
5051
} else {
@@ -56,6 +57,12 @@ export function typeInElement(element: HTMLElement, ...modifiersAndKeys: any) {
5657
k.split('').map(c => ({keyCode: c.toUpperCase().charCodeAt(0), key: c})) : [k])
5758
.reduce((arr, k) => arr.concat(k), []);
5859

60+
// Do nothing if no keys have been specified. Calling this function with no keys should
61+
// not result in a focus event being dispatched.
62+
if (keys.length === 0) {
63+
return;
64+
}
65+
5966
triggerFocus(element);
6067
for (const key of keys) {
6168
dispatchKeyboardEvent(element, 'keydown', key.keyCode, key.key, element, modifiers);

src/cdk/testing/tests/protractor.e2e.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,17 @@ describe('ProtractorHarnessEnvironment', () => {
197197
expect(await input.getProperty('value')).toBe('');
198198
});
199199

200+
it('sendKeys method should not focus element if no keys have been specified', async () => {
201+
const input = await harness.input();
202+
expect(await input.isFocused()).toBe(false);
203+
await input.sendKeys();
204+
expect(await input.isFocused()).toBe(false);
205+
await input.sendKeys('');
206+
expect(await input.isFocused()).toBe(false);
207+
await input.sendKeys('', '');
208+
expect(await input.isFocused()).toBe(false);
209+
});
210+
200211
it('should be able to click', async () => {
201212
const counter = await harness.counter();
202213
expect(await counter.text()).toBe('0');

src/cdk/testing/tests/testbed.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,17 @@ describe('TestbedHarnessEnvironment', () => {
294294
expect(await input.getProperty('value')).toBe('');
295295
});
296296

297+
it('sendKeys method should not focus element if no keys have been specified', async () => {
298+
const input = await harness.input();
299+
expect(await input.isFocused()).toBe(false);
300+
await input.sendKeys();
301+
expect(await input.isFocused()).toBe(false);
302+
await input.sendKeys('');
303+
expect(await input.isFocused()).toBe(false);
304+
await input.sendKeys('', '');
305+
expect(await input.isFocused()).toBe(false);
306+
});
307+
297308
it('should be able to click', async () => {
298309
const counter = await harness.counter();
299310
expect(await counter.text()).toBe('0');

0 commit comments

Comments
 (0)