Skip to content

Commit

Permalink
Merge pull request #747 from jaydgruber/issue-684-failing-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rwjblue authored May 5, 2020
2 parents ab7707c + ba9b22e commit 1881f3e
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 2 deletions.
39 changes: 39 additions & 0 deletions addon-test-support/@ember/test-helpers/dom/-guard-for-maxlength.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { FormControl } from './-is-form-control';

// ref: https://html.spec.whatwg.org/multipage/input.html#concept-input-apply
const constrainedInputTypes = ['text', 'search', 'url', 'tel', 'email', 'password'];

/**
@private
@param {Element} element - the element to check
@returns {boolean} `true` when the element should constrain input by the maxlength attribute, `false` otherwise
*/
function isMaxLengthConstrained(
element: Element
): element is HTMLInputElement | HTMLTextAreaElement {
return (
!!Number(element.getAttribute('maxLength')) &&
(element instanceof HTMLInputElement ||
(element instanceof HTMLTextAreaElement && constrainedInputTypes.indexOf(element.type) > -1))
);
}

/**
* @private
* @param {Element} element - the element to check
* @param {string} text - the text being added to element
* @param {string} testHelper - the test helper context the guard is called from (for Error message)
* @throws if `element` has `maxlength` & `value` exceeds `maxlength`
*/
export default function guardForMaxlength(
element: FormControl,
text: string,
testHelper: string
): void {
const maxlength = element.getAttribute('maxlength');
if (isMaxLengthConstrained(element) && maxlength && text && text.length > Number(maxlength)) {
throw new Error(
`Can not \`${testHelper}\` with text: '${text}' that exceeds maxlength: '${maxlength}'.`
);
}
}
4 changes: 3 additions & 1 deletion addon-test-support/@ember/test-helpers/dom/fill-in.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import getElement from './-get-element';
import isFormControl from './-is-form-control';
import guardForMaxlength from './-guard-for-maxlength';
import { __focus__ } from './focus';
import settled from '../settled';
import fireEvent from './fire-event';
Expand Down Expand Up @@ -50,6 +51,8 @@ export default function fillIn(target: Target, text: string): Promise<void> {
throw new Error(`Can not \`fillIn\` readonly '${target}'.`);
}

guardForMaxlength(element, text, 'fillIn');

__focus__(element);

element.value = text;
Expand All @@ -60,7 +63,6 @@ export default function fillIn(target: Target, text: string): Promise<void> {
} else {
throw new Error('`fillIn` is only usable on form controls or contenteditable elements.');
}

fireEvent(element, 'input');
fireEvent(element, 'change');

Expand Down
6 changes: 5 additions & 1 deletion addon-test-support/@ember/test-helpers/dom/type-in.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import isFormControl, { FormControl } from './-is-form-control';
import { __focus__ } from './focus';
import { Promise } from 'rsvp';
import fireEvent from './fire-event';
import guardForMaxlength from './-guard-for-maxlength';
import Target from './-target';
import { __triggerKeyEvent__ } from './trigger-key-event';
import { log } from '@ember/test-helpers/dom/-logging';
Expand Down Expand Up @@ -94,7 +95,10 @@ function keyEntry(element: FormControl, character: string): () => void {
.then(() => __triggerKeyEvent__(element, 'keydown', characterKey, options))
.then(() => __triggerKeyEvent__(element, 'keypress', characterKey, options))
.then(() => {
element.value = element.value + character;
const newValue = element.value + character;
guardForMaxlength(element, newValue, 'typeIn');

element.value = newValue;
fireEvent(element, 'input');
})
.then(() => __triggerKeyEvent__(element, 'keyup', characterKey, options));
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/dom/fill-in-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,35 @@ module('DOM Helper: fillIn', function (hooks) {
assert.strictEqual(document.activeElement, element, 'activeElement updated');
assert.equal(element.value, '');
});

test('filling an input with a maxlength with suitable value', async function (assert) {
element = buildInstrumentedElement('input');
const maxLengthString = 'f';
element.setAttribute('maxlength', maxLengthString.length);

await setupContext(context);

await fillIn(element, maxLengthString);

assert.verifySteps(clickSteps);
assert.equal(
element.value,
maxLengthString,
`fillIn respects input attribute [maxlength=${maxLengthString.length}]`
);
});

test('filling an input with a maxlength with too long value', async function (assert) {
element = buildInstrumentedElement('input');
const maxLengthString = 'f';
const tooLongString = maxLengthString.concat('oo');
element.setAttribute('maxlength', maxLengthString.length);

await setupContext(context);

assert.rejects(
fillIn(element, tooLongString),
new Error("Can not `fillIn` with text: 'foo' that exceeds maxlength: '1'.")
);
});
});
35 changes: 35 additions & 0 deletions tests/unit/dom/type-in-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,39 @@ module('DOM Helper: typeIn', function (hooks) {
assert.verifySteps(expectedEvents);
assert.equal(runcount, 1, 'debounced function only called once');
});

test('typing in an input with a maxlength with suitable value', async function (assert) {
element = buildInstrumentedElement('input');
const maxLengthString = 'foo';
element.setAttribute('maxlength', maxLengthString.length);

await setupContext(context);

await typeIn(element, maxLengthString);

assert.verifySteps(expectedEvents);
assert.equal(
element.value,
maxLengthString,
`typeIn respects input attribute [maxlength=${maxLengthString.length}]`
);
});

test('typing in an input with a maxlength with too long value', async function (assert) {
element = buildInstrumentedElement('input');
const maxLengthString = 'f';
const tooLongString = maxLengthString.concat('o');
element.setAttribute('maxlength', maxLengthString.length);

await setupContext(context);

await assert.rejects(
typeIn(element, tooLongString).finally(() => {
// should throw before the second input event (or second keyup for IE)
const expectedNumberOfSteps = isIE11 ? 6 : 8;
assert.verifySteps(expectedEvents.slice(0, expectedNumberOfSteps));
}),
new Error("Can not `typeIn` with text: 'fo' that exceeds maxlength: '1'.")
);
});
});

0 comments on commit 1881f3e

Please sign in to comment.