New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bring over DOM helper implementation. #258
Merged
Merged
Changes from all commits
Commits
Show all changes
61 commits
Select commit
Hold shift + click to select a range
f5396fa
Add `waitUntil` helper.
rwjblue 657e8d8
Add initial implementations for `click` and `focus`.
rwjblue 31e66a8
Bring over `blur` implementation.
rwjblue 4b91a8c
Add triggerEvent and triggerKeyEvent.
rwjblue 534e330
Refactor tests to use public API helpers.
rwjblue 56c6026
Guard for strings in -get-element.
rwjblue 1220ed4
Fix documentation blocks for helpers.
rwjblue 59596f8
Defaults `blur`'s element to document.activeElement.
rwjblue e5f84cd
Ensure `focus` throws if invoked with unfocusable selector.
rwjblue 51a5da8
Refactor inline docs to be consistent.
rwjblue 457333e
Refactor triggerKeyEvent to be more readable.
rwjblue 2e0cc6c
Move wait-until-test to correct location.
rwjblue 622ce97
Reorder events in `focus`.
rwjblue da7d8e5
Add unit tests for `click` helper.
rwjblue fa9f7c1
Add helpful (eager) error conditions for `click` and `getElement`.
rwjblue 05d1f00
Ensure `click` is _always_ async.
rwjblue dbbb7a3
Refactor `focus` to be always async.
rwjblue 8f55c94
Add unit tests for `focus`.
rwjblue 88beb6b
Create private `nextTick` utility.
rwjblue 043c4bc
Use `nextTick` in `waitUntil`.
rwjblue cf98536
Add monkey patch for QUnit until qunit > 2.4.1 is released.
rwjblue c919c77
Add blur unit tests.
rwjblue 58441b0
Refactor `blur`
rwjblue 1f10141
Fix stupid mistake in reexports.
rwjblue 88c88ed
Update tests to deal with async dom helpers.
rwjblue e523951
Add and utilize `nextTickPromise` helper method.
rwjblue b751706
Ensure events fired receive native event.
rwjblue d21bf56
Add unit tests for `triggerEvent`.
rwjblue fbd0353
Flesh out `triggerEvent` input validation.
rwjblue 6d17cc9
Add unit tests for triggerKeyEvent.
rwjblue 48ab310
Add input validation to triggerKeyEvent.
rwjblue 2221b42
Incorporate changes from cibernox/ember-native-dom-helpers#104.
rwjblue 83444ea
Initial implementation of `fillIn`.
rwjblue 5988674
Mark internal helper functions as private.
rwjblue 5b7da22
Fix more API doc comment blocks.
rwjblue ca88ee2
Tweak more documentation.
rwjblue 1ffe33c
Add explicit `assert.expect`.
rwjblue d91821c
Use `nextTick` to avoid time shifting issues.
rwjblue 2f34b26
Add missing test case from DOM helpers.
rwjblue 61222a5
Refactor DOM helper tests.
rwjblue b6073e4
Add tests for `fillIn`.
rwjblue ead022a
Leverage element.isContentEditable instead of local util.
rwjblue 62e22c7
Remove LINK from `FOCUSABLE_TAGS`.
rwjblue 612c815
Replace HTMLElement || SVGElement with Element.
rwjblue f2b3c35
Split "click even sequence" from `click`.
rwjblue 2cc394e
Add `tap` implementation.
rwjblue f03eead
Add unit tests for tap.
rwjblue 5c23057
Add basic `waitFor` implementation.
rwjblue 2a8b97d
More API documentation tweaks.
rwjblue caf3e13
Ensure that `waitUntil` properly handles callbacks with errors.
rwjblue 3b3d7c1
Return an array of elements for `waitFor` with `count`.
rwjblue 326b968
Add unit tests for `waitFor`.
rwjblue fdefbc9
Remove tests requiring `click` only wait for subset of settledness.
rwjblue 95b34ee
Add basic `assert.rejects` infrastructure.
rwjblue adb006b
Make argument assertions into rejections.
rwjblue 7ee206a
Refactor manual rejection assertions to assert.rejects.
rwjblue 7e41f7f
Update `moduleForAcceptance` interop test to use `click`.
rwjblue e6f8668
Add comment RE: eager error creation without throwing.
rwjblue 0412bbf
Add helpful errors to helpers for `selector|element` arg.
rwjblue d07492b
Ensure `triggerKeyEvent` rejects (and doesn't throw eagerly).
rwjblue 1848f83
Validate `target` in `waitFor`.
rwjblue File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { Promise } from 'rsvp'; | ||
|
||
export const nextTick = setTimeout; | ||
|
||
export function nextTickPromise() { | ||
return new Promise(resolve => { | ||
nextTick(resolve); | ||
}); | ||
} |
21 changes: 21 additions & 0 deletions
21
addon-test-support/@ember/test-helpers/dom/-get-element.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { getContext } from '../setup-context'; | ||
|
||
export default function getElement(selectorOrElement) { | ||
if ( | ||
selectorOrElement instanceof Window || | ||
selectorOrElement instanceof Document || | ||
selectorOrElement instanceof Element | ||
) { | ||
return selectorOrElement; | ||
} else if (typeof selectorOrElement === 'string') { | ||
let context = getContext(); | ||
let rootElement = context && context.element; | ||
if (!rootElement) { | ||
throw new Error(`Must setup rendering context before attempting to interact with elements.`); | ||
} | ||
|
||
return rootElement.querySelector(selectorOrElement); | ||
} else { | ||
throw new Error('Must use an element or a selector string'); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
addon-test-support/@ember/test-helpers/dom/-is-focusable.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import isFormControl from './-is-form-control'; | ||
|
||
const FOCUSABLE_TAGS = ['A']; | ||
export default function isFocusable(element) { | ||
if ( | ||
isFormControl(element) || | ||
element.isContentEditable || | ||
FOCUSABLE_TAGS.indexOf(element.tagName) > -1 | ||
) { | ||
return true; | ||
} | ||
|
||
return element.hasAttribute('tabindex'); | ||
} |
11 changes: 11 additions & 0 deletions
11
addon-test-support/@ember/test-helpers/dom/-is-form-control.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const FORM_CONTROL_TAGS = ['INPUT', 'BUTTON', 'SELECT', 'TEXTAREA']; | ||
|
||
export default function isFormControl(el) { | ||
let { tagName, type } = el; | ||
|
||
if (type === 'hidden') { | ||
return false; | ||
} | ||
|
||
return FORM_CONTROL_TAGS.indexOf(tagName) > -1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import getElement from './-get-element'; | ||
import fireEvent from './fire-event'; | ||
import settled from '../settled'; | ||
import isFocusable from './-is-focusable'; | ||
import { nextTickPromise } from '../-utils'; | ||
|
||
/** | ||
@private | ||
@method __blur__ | ||
@param {Element} element | ||
*/ | ||
export function __blur__(element) { | ||
let browserIsNotFocused = document.hasFocus && !document.hasFocus(); | ||
|
||
// makes `document.activeElement` be `body`. | ||
// If the browser is focused, it also fires a blur event | ||
element.blur(); | ||
|
||
// Chrome/Firefox does not trigger the `blur` event if the window | ||
// does not have focus. If the document does not have focus then | ||
// fire `blur` event via native event. | ||
if (browserIsNotFocused) { | ||
fireEvent(element, 'blur', { bubbles: false }); | ||
fireEvent(element, 'focusout'); | ||
} | ||
} | ||
|
||
/** | ||
@method blur | ||
@param {String|Element} [target=document.activeElement] the element to blur | ||
@return {Promise<void>} | ||
@public | ||
*/ | ||
export default function blur(target = document.activeElement) { | ||
return nextTickPromise().then(() => { | ||
let element = getElement(target); | ||
if (!element) { | ||
throw new Error(`Element not found when calling \`blur('${target}')\`.`); | ||
} | ||
|
||
if (!isFocusable(element)) { | ||
throw new Error(`${target} is not focusable`); | ||
} | ||
|
||
__blur__(element); | ||
|
||
return settled(); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import getElement from './-get-element'; | ||
import fireEvent from './fire-event'; | ||
import { __focus__ } from './focus'; | ||
import settled from '../settled'; | ||
import isFocusable from './-is-focusable'; | ||
import { nextTickPromise } from '../-utils'; | ||
|
||
/** | ||
@private | ||
@method __click__ | ||
@param {Element} element | ||
*/ | ||
export function __click__(element) { | ||
fireEvent(element, 'mousedown'); | ||
|
||
if (isFocusable(element)) { | ||
__focus__(element); | ||
} | ||
|
||
fireEvent(element, 'mouseup'); | ||
fireEvent(element, 'click'); | ||
} | ||
|
||
/** | ||
@method click | ||
@param {String|Element} target | ||
@return {Promise<void>} | ||
@public | ||
*/ | ||
export default function click(target) { | ||
return nextTickPromise().then(() => { | ||
if (!target) { | ||
throw new Error('Must pass an element or selector to `click`.'); | ||
} | ||
|
||
let element = getElement(target); | ||
if (!element) { | ||
throw new Error(`Element not found when calling \`click('${target}')\`.`); | ||
} | ||
|
||
__click__(element); | ||
return settled(); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import getElement from './-get-element'; | ||
import isFormControl from './-is-form-control'; | ||
import { __focus__ } from './focus'; | ||
import settled from '../settled'; | ||
import fireEvent from './fire-event'; | ||
import { nextTickPromise } from '../-utils'; | ||
|
||
/* | ||
@method fillIn | ||
@param {String|Element} target | ||
@param {String} text | ||
@return {Promise<void>} | ||
@public | ||
*/ | ||
export default function fillIn(target, text) { | ||
return nextTickPromise().then(() => { | ||
if (!target) { | ||
throw new Error('Must pass an element or selector to `fillIn`.'); | ||
} | ||
|
||
let element = getElement(target); | ||
if (!element) { | ||
throw new Error(`Element not found when calling \`fillIn('${target}')\`.`); | ||
} | ||
|
||
if (!isFormControl(element) && !element.isContentEditable) { | ||
throw new Error('`fillIn` is only usable on form controls or contenteditable elements.'); | ||
} | ||
|
||
if (!text) { | ||
throw new Error('Must provide `text` when calling `fillIn`.'); | ||
} | ||
|
||
__focus__(element); | ||
|
||
if (element.isContentEditable) { | ||
element.innerHTML = text; | ||
} else { | ||
element.value = text; | ||
} | ||
|
||
fireEvent(element, 'input'); | ||
fireEvent(element, 'change'); | ||
|
||
return settled(); | ||
}); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could improve the logic here. I don't think that disabled buttons or inputs should be focusable.
I found this nice table we can copy from, even if we're not soooo exhaustive: https://allyjs.io/data-tables/focusable.html