@testing-library/dom#fireEvent JavaScript Examples
The following examples show how to use
@testing-library/dom#fireEvent.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ProfileDOMTestingLib.test.js From Simplify-Testing-with-React-Testing-Library with MIT License | 6 votes |
test('Profile, given click "hide details" button, shows "display details" button', () => {
const div = document.createElement('div');
ReactDOM.render(
<Profile
name='John Doe'
title='Team Lead'
details='This is my 5th year and I love helping others'
/>,
div
);
document.body.appendChild(div);
const hideDetailsBtn = screen.getByRole('button', { name: /hide details/i });
fireEvent.click(hideDetailsBtn);
const displayDetailsBtn = screen.getByRole('button', {
name: /display details/i,
});
expect(displayDetailsBtn.textContent).toEqual('Display Details');
const removedHideDetailsBtn = screen.queryByRole('button', {
name: /hide details/i,
});
expect(removedHideDetailsBtn).not.toBeInTheDocument();
// Test cleanup
div.remove();
});
Example #2
Source File: LibraryAccessForm.spec.jsx From frontend-app-library-authoring with GNU Affero General Public License v3.0 | 6 votes |
testSuite('<LibraryAccessForm />', () => {
it('Renders an error for the email field', async () => {
const library = libraryFactory();
const props = { library, errorFields: { email: 'Too difficult to remember.' }, ...commonMocks() };
const { container } = await ctxRender(<LibraryAccessFormContainer {...props} />);
expect(getByText(container, /Too difficult/)).toBeTruthy();
});
it('Submits and adds a new user.', async () => {
const library = libraryFactory();
const props = { library, ...commonMocks() };
const { addUser } = props;
const user = userFactory();
addUser.mockImplementation(() => immediate(user));
const { container } = await ctxRender(<LibraryAccessFormContainer {...props} />);
const emailField = getByLabelText(container, 'Email');
fireEvent.change(emailField, { target: { value: '[email protected]' } });
const submitButton = getByRole(container, 'button', { name: /Submit/ });
fireEvent.click(submitButton);
await waitFor(() => expect(addUser).toHaveBeenCalledWith({
libraryId: library.id, data: { email: '[email protected]', access_level: LIBRARY_ACCESS.READ },
}));
expect(emailField.value).toBe('');
});
it('Closes out', async () => {
const library = libraryFactory();
const props = { library, ...commonMocks() };
const { setShowAdd } = props;
const { container } = await ctxRender(
<LibraryAccessFormContainer
{...props}
/>,
);
const button = getByRole(container, 'button', { name: /Cancel/ });
fireEvent.click(button);
expect(setShowAdd).toHaveBeenCalledWith(false);
});
});
Example #3
Source File: shared.js From emoji-picker-element with Apache License 2.0 | 6 votes |
export async function openSkintoneListbox (container) {
await waitFor(() => expect(getByRole(container, 'button', { name: /Choose a skin tone/ }))
.toBeVisible())
expect(queryAllByRole(container, 'listbox', { name: 'Skin tones' })).toHaveLength(0)
await fireEvent.click(getByRole(container, 'button', { name: /Choose a skin tone/ }))
await waitFor(() => expect(getByRole(container, 'listbox', { name: 'Skin tones' })).toBeVisible())
expect(getAllByRole(container, 'option')).toHaveLength(6)
getByRole(container, 'option', { name: 'Default', selected: true }).focus()
await waitFor(() => expect(getByRole(container, 'option', { name: 'Default', selected: true }))
.toBeVisible())
// JSDom doesn't fire transitionend events, so we do it manually here
// https://github.com/jsdom/jsdom/issues/1781#issuecomment-467935000
fireEvent(getByRole(container, 'listbox', { name: 'Skin tones' }), new Event('transitionend'))
}
Example #4
Source File: unit.spec.js From js-test-basic with MIT License | 6 votes |
it('- 버튼 클릭시 counter의 dec()를 호출한 후 다시 렌더링한다.', () => {
let value = 10;
const counterDec = jest.fn().mockImplementation(() => {
value = 9;
});
createCounter.mockImplementation(() => ({
val: () => value,
isMin: () => false,
isMax: () => false,
dec: counterDec
}));
createUICounter(container);
fireEvent.click(getByText(container, '-'));
expect(counterDec).toHaveBeenCalled();
expect(getByText(container, '9')).toBeVisible();
});
Example #5
Source File: unit.spec.js From js-test-basic with MIT License | 6 votes |
it('+ 버튼 클릭시 counter의 inc()를 호출한 후 다시 렌더링한다.', () => {
let value = 10;
const counterInc = jest.fn().mockImplementation(() => {
value = 11;
});
createCounter.mockImplementation(() => ({
val: () => value,
isMin: () => false,
isMax: () => false,
inc: counterInc
}));
createUICounter(container);
fireEvent.click(getByText(container, '+'));
expect(counterInc).toHaveBeenCalled();
expect(getByText(container, '11')).toBeVisible();
});
Example #6
Source File: index.js From Path-Finding-Visualizer with MIT License | 6 votes |
function clickLabel(label) {
fireEvent.mouseOver(label);
fireEvent.mouseMove(label);
fireEvent.mouseDown(label);
fireEvent.mouseUp(label);
if (label.htmlFor) {
const input = document.getElementById(label.htmlFor);
input.focus();
fireEvent.click(label);
} else {
const input = label.querySelector("input,textarea,select");
input.focus();
label.focus();
fireEvent.click(label);
}
}
Example #7
Source File: Login.test.js From Simplify-Testing-with-React-Testing-Library with MIT License | 6 votes |
test('Login, given credentials, returns enabled submit button', () => {
const div = document.createElement('div');
ReactDOM.render(<Login />, div);
document.body.appendChild(div);
const username = screen.getByRole('textbox', { name: /username/i });
const password = screen.getByLabelText(/password/i);
const rememberMe = screen.getByRole('checkbox');
const loginBtn = screen.getByRole('button', { name: /login/i });
const fakeUser = {
username: 'test user',
password: '123password',
};
fireEvent.change(username, { target: { value: fakeUser.username } });
fireEvent.change(password, { target: { value: fakeUser.password } });
fireEvent.click(rememberMe);
expect(screen.getByTestId('form')).toHaveFormValues({
username: fakeUser.username,
password: fakeUser.password,
rememberMe: true,
});
expect(loginBtn).not.toBeDisabled();
// Test cleanup
div.remove();
});
Example #8
Source File: index.js From Path-Finding-Visualizer with MIT License | 6 votes |
function selectOption(select, option) {
fireEvent.mouseOver(option);
fireEvent.mouseMove(option);
fireEvent.mouseDown(option);
fireEvent.focus(option);
fireEvent.mouseUp(option);
fireEvent.click(option);
option.selected = true;
fireEvent.change(select);
}
Example #9
Source File: index.js From Path-Finding-Visualizer with MIT License | 6 votes |
function dblClickCheckbox(checkbox) {
fireEvent.mouseOver(checkbox);
fireEvent.mouseMove(checkbox);
fireEvent.mouseDown(checkbox);
fireEvent.mouseUp(checkbox);
fireEvent.click(checkbox);
fireEvent.mouseDown(checkbox);
fireEvent.mouseUp(checkbox);
fireEvent.click(checkbox);
}
Example #10
Source File: index.js From Path-Finding-Visualizer with MIT License | 6 votes |
function dblClickElement(element) {
fireEvent.mouseOver(element);
fireEvent.mouseMove(element);
fireEvent.mouseDown(element);
element.focus();
fireEvent.mouseUp(element);
fireEvent.click(element);
fireEvent.mouseDown(element);
fireEvent.mouseUp(element);
fireEvent.click(element);
fireEvent.dblClick(element);
const labelAncestor = findTagInParents(element, "LABEL");
labelAncestor && clickLabel(labelAncestor);
}
Example #11
Source File: index.js From Path-Finding-Visualizer with MIT License | 6 votes |
function clickElement(element) {
fireEvent.mouseOver(element);
fireEvent.mouseMove(element);
fireEvent.mouseDown(element);
element.focus();
fireEvent.mouseUp(element);
fireEvent.click(element);
const labelAncestor = findTagInParents(element, "LABEL");
labelAncestor && clickLabel(labelAncestor);
}
Example #12
Source File: index.js From Path-Finding-Visualizer with MIT License | 6 votes |
function clickBooleanElement(element) {
if (element.disabled) return;
fireEvent.mouseOver(element);
fireEvent.mouseMove(element);
fireEvent.mouseDown(element);
fireEvent.mouseUp(element);
fireEvent.click(element);
}
Example #13
Source File: index.js From Path-Finding-Visualizer with MIT License | 5 votes |
function fireChangeEvent(event) {
fireEvent.change(event.target);
event.target.removeEventListener("blur", fireChangeEvent);
}
Example #14
Source File: dataSource.test.js From emoji-picker-element with Apache License 2.0 | 5 votes |
describe('dataSource test', () => {
beforeEach(basicBeforeEach)
afterEach(basicAfterEach)
test('emoji with no shortcodes still work', async () => {
mockDataSourceWithNoShortcodes()
const dataSource = NO_SHORTCODES
const picker = new Picker({ dataSource, locale: 'en-no-shortcodes' })
document.body.appendChild(picker)
const container = picker.shadowRoot.querySelector('.picker')
await tick(20)
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /?/ })).toBeVisible())
// no shortcodes, no title
expect(getByRole(container, 'menuitem', { name: /?/ }).getAttribute('title')).toStrictEqual('')
expect(getByRole(container, 'menuitem', { name: /?/ }).getAttribute('aria-label')).toStrictEqual('?')
await picker.database.delete()
await tick(20)
document.body.removeChild(picker)
await tick(20)
})
test('emoji with emojibase v5 data source still work', async () => {
mockEmojibaseV5DataSource()
const dataSource = EMOJIBASE_V5
const picker = new Picker({ dataSource, locale: 'en-emojibase' })
document.body.appendChild(picker)
const container = picker.shadowRoot.querySelector('.picker')
await tick(20)
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /?/ })).toBeVisible())
// no shortcodes, no title
expect(getByRole(container, 'menuitem', { name: /?/ }).getAttribute('title')).toStrictEqual('gleeful')
expect(getByRole(container, 'menuitem', { name: /?/ }).getAttribute('aria-label')).toStrictEqual('?, gleeful')
await picker.database.delete()
await tick(20)
document.body.removeChild(picker)
await tick(20)
})
test('emoji with array skin tones work', async () => {
mockDataSourceWithArraySkinTones()
const dataSource = WITH_ARRAY_SKIN_TONES
const picker = new Picker({ dataSource, locale: 'en-arrayskintones' })
document.body.appendChild(picker)
const container = picker.shadowRoot.querySelector('.picker')
await tick(20)
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /?/ })).toBeVisible())
await fireEvent.click(getByRole(container, 'tab', { name: /People and body/ }))
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /???/ })).toBeVisible())
await openSkintoneListbox(container)
await fireEvent.click(getByRole(container, 'option', { name: /Medium-Dark/ }))
// both people in the emoji should have the same skin tone
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /?????/ })).toBeVisible())
await picker.database.delete()
await tick(20)
document.body.removeChild(picker)
await tick(20)
})
})
Example #15
Source File: noResizeObserver.test.js From emoji-picker-element with Apache License 2.0 | 5 votes |
// TODO: we can remove these tests when/if we stop supporting browsers without ResizeObserver
// https://caniuse.com/resizeobserver
describe('ResizeObserver unsupported', () => {
let picker
let container
let oldResizeObserver
beforeEach(async () => {
basicBeforeEach()
oldResizeObserver = global.ResizeObserver
delete global.ResizeObserver
resetResizeObserverSupported()
picker = new Picker({ dataSource: ALL_EMOJI })
document.body.appendChild(picker)
container = picker.shadowRoot.querySelector('.picker')
await tick(40)
})
afterEach(async () => {
await tick(40)
document.body.removeChild(picker)
await tick(40)
await new Database({ dataSource: ALL_EMOJI }).delete()
await tick(40)
await basicAfterEach()
global.ResizeObserver = oldResizeObserver
resetResizeObserverSupported()
})
test('basic picker test', async () => {
const numInGroup1 = truncatedEmoji.filter(_ => _.group === 0).length
const numInGroup2 = truncatedEmoji.filter(_ => _.group === 1).length
await waitFor(() => expect(getByRole(container, 'button', { name: 'Choose a skin tone (currently Default)' })).toBeVisible())
expect(getAllByRole(container, 'tab')).toHaveLength(groups.length)
expect(getByRole(container, 'tab', { name: 'Smileys and emoticons', selected: true })).toBeVisible()
await waitFor(() => expect(
testingLibrary.getAllByRole(getByRole(container, 'tabpanel'), 'menuitem')).toHaveLength(numInGroup1)
)
expect(getByRole(container, 'tab', { name: 'People and body' })).toBeVisible()
fireEvent.click(getByRole(container, 'tab', { name: 'People and body' }))
await waitFor(() => expect(
testingLibrary.getAllByRole(getByRole(container, 'tabpanel'), 'menuitem')).toHaveLength(numInGroup2))
expect(getByRole(container, 'tab', { name: 'People and body', selected: true })).toBeVisible()
})
})
Example #16
Source File: index.js From Path-Finding-Visualizer with MIT License | 4 votes |
userEvent = {
click(element) {
const focusedElement = element.ownerDocument.activeElement;
const wasAnotherElementFocused =
focusedElement !== element.ownerDocument.body &&
focusedElement !== element;
if (wasAnotherElementFocused) {
fireEvent.mouseMove(focusedElement);
fireEvent.mouseLeave(focusedElement);
}
switch (element.tagName) {
case "LABEL":
clickLabel(element);
break;
case "INPUT":
if (element.type === "checkbox" || element.type === "radio") {
clickBooleanElement(element);
break;
}
default:
clickElement(element);
}
wasAnotherElementFocused && focusedElement.blur();
},
dblClick(element) {
const focusedElement = document.activeElement;
const wasAnotherElementFocused =
focusedElement !== document.body && focusedElement !== element;
if (wasAnotherElementFocused) {
fireEvent.mouseMove(focusedElement);
fireEvent.mouseLeave(focusedElement);
}
switch (element.tagName) {
case "INPUT":
if (element.type === "checkbox") {
dblClickCheckbox(element);
break;
}
default:
dblClickElement(element);
}
wasAnotherElementFocused && focusedElement.blur();
},
selectOptions(element, values) {
const focusedElement = document.activeElement;
const wasAnotherElementFocused =
focusedElement !== document.body && focusedElement !== element;
if (wasAnotherElementFocused) {
fireEvent.mouseMove(focusedElement);
fireEvent.mouseLeave(focusedElement);
}
clickElement(element);
const valArray = Array.isArray(values) ? values : [values];
const selectedOptions = Array.from(element.children).filter(
opt => opt.tagName === "OPTION" && valArray.includes(opt.value)
);
if (selectedOptions.length > 0) {
if (element.multiple) {
selectedOptions.forEach(option => selectOption(element, option));
} else {
selectOption(element, selectedOptions[0]);
}
}
wasAnotherElementFocused && focusedElement.blur();
},
async type(element, text, userOpts = {}) {
if (element.disabled) return;
const defaultOpts = {
allAtOnce: false,
delay: 0
};
const opts = Object.assign(defaultOpts, userOpts);
if (opts.allAtOnce) {
if (element.readOnly) return;
fireEvent.input(element, { target: { value: text } });
} else {
let actuallyTyped = "";
for (let index = 0; index < text.length; index++) {
const char = text[index];
const key = char; // TODO: check if this also valid for characters with diacritic markers e.g. úé etc
const keyCode = char.charCodeAt(0);
if (opts.delay > 0) await wait(opts.delay);
const downEvent = fireEvent.keyDown(element, {
key: key,
keyCode: keyCode,
which: keyCode
});
if (downEvent) {
const pressEvent = fireEvent.keyPress(element, {
key: key,
keyCode,
charCode: keyCode
});
if (pressEvent) {
actuallyTyped += key;
if (!element.readOnly)
fireEvent.input(element, {
target: {
value: actuallyTyped
},
bubbles: true,
cancelable: true
});
}
}
fireEvent.keyUp(element, {
key: key,
keyCode: keyCode,
which: keyCode
});
}
}
element.addEventListener("blur", fireChangeEvent);
},
tab({ shift = false, focusTrap = document } = {}) {
const focusableElements = focusTrap.querySelectorAll(
"input, button, select, textarea, a[href], [tabindex]"
);
const list = Array.prototype.filter
.call(focusableElements, function(item) {
return item.getAttribute("tabindex") !== "-1";
})
.sort((a, b) => {
const tabIndexA = a.getAttribute("tabindex");
const tabIndexB = b.getAttribute("tabindex");
return tabIndexA < tabIndexB ? -1 : tabIndexA > tabIndexB ? 1 : 0;
});
const index = list.indexOf(document.activeElement);
let nextIndex = shift ? index - 1 : index + 1;
let defaultIndex = shift ? list.length - 1 : 0;
const next = list[nextIndex] || list[defaultIndex];
if (next.getAttribute("tabindex") === null) {
next.setAttribute("tabindex", "0"); // jsdom requires tabIndex=0 for an item to become 'document.activeElement' (the browser does not)
next.focus();
next.removeAttribute("tabindex"); // leave no trace. :)
} else {
next.focus();
}
}
}
Example #17
Source File: ProjectDetails.test.jsx From ui with MIT License | 4 votes |
describe('ProjectDetails', () => {
let metadataCreated;
beforeEach(() => {
jest.clearAllMocks();
metadataCreated = jest.spyOn(createMetadataTrack, 'default');
});
it('Has a title, project ID and description', () => {
render(
<Provider store={mockStore(noDataState)}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
// Project name
expect(screen.getByText(experimentName)).toBeDefined();
// Project uuid
expect(screen.queryByText(experiment1id)).toBeDefined();
// Description
expect(screen.queryByText(experimentDescription)).toBeDefined();
});
it('Has 4 buttons', () => {
render(
<Provider store={mockStore(noDataState)}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
expect(screen.getByText('Add samples')).toBeDefined();
expect(screen.getByText('Add metadata')).toBeDefined();
expect(screen.getByText('Download')).toBeDefined();
expect(screen.getByText('Process project')).toBeDefined();
});
it('Add metadata button is disabled if there is no data', () => {
render(
<Provider store={mockStore(noDataState)}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
const metadataButton = screen.getByText('Add metadata').closest('button');
expect(metadataButton).toBeDisabled();
});
it('Add metadata button is enabled if there is data', () => {
render(
<Provider store={mockStore(withDataState)}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
const metadataButton = screen.getByText('Add metadata').closest('button');
expect(metadataButton).not.toBeDisabled();
});
it('Download dropdown is disabled if there are no samples', () => {
const store = createStore(rootReducer, _.cloneDeep(noDataState), applyMiddleware(thunk));
render(
<Provider store={store}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
const downloadDropdown = screen.getByText('Download').closest('button');
expect(downloadDropdown).toBeDisabled();
});
it('Shows all the samples that are uploaded', () => {
render(
<Provider store={mockStore(withDataState)}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
expect(screen.getByText(sample1Name)).toBeDefined();
expect(screen.getByText(sample2Name)).toBeDefined();
});
it('Creates a metadata column', async () => {
const store = createStore(rootReducer, _.cloneDeep(withDataState), applyMiddleware(thunk));
await act(async () => {
render(
<Provider store={store}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
});
const addMetadata = screen.getByText('Add metadata');
userEvent.click(addMetadata);
const field = screen.getByRole('textbox');
userEvent.type(field, 'myBrandNewMetadata');
fireEvent.keyDown(field, { key: 'Enter', code: 'Enter' });
await waitFor(() => expect(metadataCreated).toBeCalledTimes(1));
});
it('Cancels metadata creation', () => {
const store = createStore(rootReducer, _.cloneDeep(withDataState), applyMiddleware(thunk));
render(
<Provider store={store}>
<ProjectDetails width={width} height={height} />
</Provider>,
);
const addMetadata = screen.getByText('Add metadata');
userEvent.click(addMetadata);
const field = screen.getByRole('textbox');
userEvent.type(field, 'somenewMeta');
fireEvent.keyDown(field, { key: 'Escape', code: 'Escape' });
expect(store.getState().experiments[experiment1id].metadataKeys).toEqual(['metadata-1']);
});
});
Example #18
Source File: favorites.test.js From emoji-picker-element with Apache License 2.0 | 4 votes |
describe('Favorites UI', () => {
let picker
let container
beforeEach(async () => {
basicBeforeEach()
const dataWithFavorites = uniqBy([
...truncatedEmoji,
...allData.filter(_ => MOST_COMMONLY_USED_EMOJI.includes(_.emoji))
], _ => _.emoji)
fetch.get(dataSource, () => new Response(JSON.stringify(dataWithFavorites), { headers: { ETag: 'W/favs' } }))
fetch.head(dataSource, () => new Response(null, { headers: { ETag: 'W/favs' } }))
picker = new Picker({ dataSource, locale: 'en' })
document.body.appendChild(picker)
container = picker.shadowRoot.querySelector('.picker')
await tick(40)
})
afterEach(async () => {
await tick(40)
document.body.removeChild(picker)
await tick(40)
await basicAfterEach()
})
async function remount () {
await tick(40)
document.body.removeChild(picker)
await tick(40)
document.body.appendChild(picker)
container = picker.shadowRoot
await tick(40)
}
test('Favorites UI basic test', async () => {
let favoritesBar = getByRole(container, 'menu', { name: 'Favorites' })
expect(favoritesBar).toBeVisible()
await waitFor(() => expect(getAllByRole(favoritesBar, 'menuitem')).toHaveLength(8))
expect(getAllByRole(favoritesBar, 'menuitem').map(_ => _.getAttribute('id').substring(4))).toStrictEqual(
MOST_COMMONLY_USED_EMOJI.slice(0, 8)
)
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /?/ })).toBeVisible())
fireEvent.click(getByRole(container, 'menuitem', { name: /?/ }))
// have to unmount/remount to force a favorites refresh
await remount()
favoritesBar = getByRole(container, 'menu', { name: 'Favorites' })
await waitFor(() => expect(getAllByRole(favoritesBar, 'menuitem')
.map(_ => _.getAttribute('id').substring(4))).toStrictEqual([
'?',
...MOST_COMMONLY_USED_EMOJI.slice(0, 7)
]
))
})
test('Favorites with custom emoji', async () => {
const transparent = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
const black = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='
const customEmoji = [
{
name: 'transparent',
shortcodes: ['transparent'],
url: transparent
},
{
name: 'black',
shortcodes: ['black'],
url: black
}
]
await waitFor(() => expect(getAllByRole(container, 'tab')).toHaveLength(groups.length))
// when setting custom emoji, they can appear in the favorites
await tick(40)
picker.customEmoji = customEmoji
await tick(40)
await waitFor(() => expect(getAllByRole(container, 'tab')).toHaveLength(groups.length + 1))
expect(getByRole(container, 'tab', { name: 'Custom', selected: true })).toBeVisible()
await tick(40)
await waitFor(() => expect(queryAllByRole(container, 'menuitem', { name: /transparent/i })).toHaveLength(1), {
timeout: 5000
})
await waitFor(() => expect(getByRole(container, 'menuitem', { name: /transparent/i })).toBeVisible(), {
timeout: 3000
})
fireEvent.click(getByRole(container, 'menuitem', { name: /transparent/i }))
fireEvent.click(getByRole(container, 'menuitem', { name: /black/i }))
// have to unmount/remount to force a favorites refresh
await remount()
await waitFor(
() => expect(getByRole(getByRole(container, 'menu', { name: 'Favorites' }), 'menuitem', { name: /transparent/i })).toBeVisible
)
await waitFor(
() => expect(getByRole(getByRole(container, 'menu', { name: 'Favorites' }), 'menuitem', { name: /black/i })).toBeVisible
)
// when setting custom emoji back to [], the favorites bar removes the custom emoji
picker.customEmoji = []
await waitFor(() => expect(getAllByRole(container, 'tab')).toHaveLength(groups.length))
await waitFor(
() => expect(queryAllByRole(getByRole(container, 'menu', { name: 'Favorites' }), 'menuitem', { name: /transparent/i })).toHaveLength(0)
)
await waitFor(
() => expect(queryAllByRole(getByRole(container, 'menu', { name: 'Favorites' }), 'menuitem', { name: /black/i })).toHaveLength(0)
)
})
})
Example #19
Source File: LibraryAuthoringPage.spec.jsx From frontend-app-library-authoring with GNU Affero General Public License v3.0 | 4 votes |
testSuite('<LibraryAuthoringPageContainer />', () => {
it('Fetches a library when missing', async () => {
await ctxRender(
<LibraryAuthoringPageContainer
match={{ params: { libraryId: 'testtest' } }}
/>,
);
await waitFor(() => expect(clearLibrary.fn).toHaveBeenCalled());
clearLibrary.calls[0].resolve();
await waitFor(() => expect(fetchLibraryDetail.fn).toHaveBeenCalledWith({ libraryId: 'testtest' }));
});
it('Fetches a library when the current library does not match', async () => {
await ctxRender(
<LibraryAuthoringPageContainer
match={{ params: { libraryId: 'testtest' } }}
/>,
genState(libraryFactory()),
);
await waitFor(() => expect(clearLibrary.fn).toHaveBeenCalled());
clearLibrary.calls[0].resolve();
await waitFor(() => expect(fetchLibraryDetail.fn).toHaveBeenCalledWith({ libraryId: 'testtest' }));
});
it('Does not refetch the library if it matches', async () => {
const library = libraryFactory();
await render(library, genState(library));
await process.nextTick(() => {
expect(clearLibrary.fn).not.toHaveBeenCalled();
});
});
it('Loads blocks', async () => {
const library = libraryFactory();
const blocks = makeN(blockFactoryLine([], { library }), 2);
await render(library, genState(library, blocks));
expect(screen.getByText(blocks[0].display_name)).toBeTruthy();
expect(screen.getByText(blocks[1].display_name)).toBeTruthy();
});
it('Toggles Previews', async () => {
const library = libraryFactory();
const blocks = [blockFactory(undefined, { library })];
await render(library, genState(library, blocks));
expect(screen.getByTestId('block-preview')).toBeTruthy();
screen.getAllByText('Hide Previews')[0].click();
await waitFor(() => expect(() => screen.getByTestId('block-preview')).toThrow());
expect(localStorage.getItem('showPreviews')).toBe('false');
});
it('Fetches block information', async () => {
const library = libraryFactory();
const blocks = [blockFactory({ id: 'testBlock' }, { library })];
const storeConfig = genState(library, blocks);
// Remove the local info about blocks.
storeConfig.storeOptions.preloadedState[STORE_NAMES.BLOCKS].blocks = {};
await render(library, storeConfig);
// There should be no previews because this info hasn't loaded yet.
await waitFor(() => expect(() => screen.getByTestId('block-preview')).toThrow());
expect(initializeBlock.fn).toHaveBeenCalledWith({ blockId: 'testBlock' });
initializeBlock.calls[0].dispatch(libraryBlockActions.libraryEnsureBlock({ blockId: 'testBlock' }));
await waitFor(() => expect(fetchLibraryBlockView.fn).toHaveBeenCalledWith(
{
blockId: 'testBlock', viewName: 'student_view', viewSystem: 'studio',
},
));
expect(fetchLibraryBlockView.fn).toHaveBeenCalledTimes(1);
});
it('Fetches block LTI URL to clipboard', async () => {
const library = libraryFactory({ allow_lti: true });
const blocks = makeN(blockFactoryLine([], { library }), 2);
await render(library, genState(library, blocks));
expect(screen.getByText(blocks[0].display_name)).toBeTruthy();
expect(screen.getByText(blocks[1].display_name)).toBeTruthy();
const copyToClipboardButtons = screen.getAllByText('Copy LTI Url');
expect(copyToClipboardButtons.length).toBe(2);
copyToClipboardButtons[0].click();
await waitFor(() => fetchBlockLtiUrl.calls[0].dispatch(
libraryAuthoringActions.libraryBlockLtiUrlFetchRequest({ blockId: blocks[0].id }),
));
expect(fetchBlockLtiUrl.fn).toHaveBeenCalledWith({ blockId: blocks[0].id });
await waitFor(() => fetchBlockLtiUrl.calls[0].dispatch(
libraryAuthoringActions.libraryAuthoringSuccess({
value: { blockId: blocks[0], lti_url: 'a' },
attr: 'ltiUrlClipboard',
}),
));
});
it('Copy LTI URL not shown unless it is enabled', async () => {
const library = libraryFactory();
const blocks = makeN(blockFactoryLine([], { library }), 2);
await render(library, genState(library, blocks));
expect(screen.getByText(blocks[0].display_name)).toBeTruthy();
expect(screen.getByText(blocks[1].display_name)).toBeTruthy();
const copyToClipboardButtons = screen.queryAllByAltText('Copy LTI Url');
expect(copyToClipboardButtons.length).toBe(0);
});
it('Adds a predefined block type', async () => {
const library = libraryFactory({ type: LIBRARY_TYPES.VIDEO });
await render(library, genState(library));
const addButtons = screen.getAllByText('Add Video');
// One's hidden by CSS, but the testing library wouldn't know that.
expect(addButtons.length).toBe(3);
addButtons[0].click();
expect(createBlock.fn).toHaveBeenCalledWith({
libraryId: library.id,
data: {
block_type: VIDEO_TYPE.block_type,
definition_id: expect.any(String),
},
query: '',
types: [],
paginationParams,
});
});
it('Adds a custom block type', async () => {
const library = libraryFactory({
blockTypes: [{ display_name: 'Test Type', block_type: 'test' }],
type: LIBRARY_TYPES.COMPLEX,
});
await render(library, genState(library));
screen.getByText('Advanced').click();
const typeOption = await screen.findByText('Test Type', { ignore: 'option' });
act(() => {
typeOption.click();
});
await waitFor(() => expect(createBlock.fn).toHaveBeenCalledWith({
libraryId: library.id,
data: {
block_type: 'test',
definition_id: expect.any(String),
},
query: '',
types: [],
paginationParams,
}));
});
[VIDEO_TYPE, PROBLEM_TYPE, HTML_TYPE].forEach((blockDef) => {
it(`Adds a ${blockDef.display_name} block to a library`, async () => {
const library = libraryFactory({ type: LIBRARY_TYPES.COMPLEX });
await render(library, genState(library));
screen.getByText('Advanced').click();
const typeOption = await screen.findByText(blockDef.display_name, { ignore: 'option' });
act(() => {
typeOption.click();
});
expect(createBlock.fn).toHaveBeenCalledWith({
libraryId: library.id,
data: {
block_type: blockDef.block_type,
definition_id: expect.any(String),
},
query: '',
types: [],
paginationParams,
});
});
});
it('Searches for blocks', async () => {
const library = libraryFactory();
await render(library, genState(library));
const search = screen.getByLabelText('Search...');
act(() => {
fireEvent.change(search, { target: { value: 'boop' } });
});
await waitFor(() => expect(searchLibrary.fn).toHaveBeenCalledWith({
libraryId: library.id,
query: 'boop',
types: [],
paginationParams,
}));
});
it('Filters blocks by type', async () => {
const library = libraryFactory();
await render(library, genState(library));
const filter = screen.getByTestId('filter-dropdown');
act(() => {
fireEvent.change(filter, { target: { value: 'html' } });
});
await waitFor(() => expect(searchLibrary.fn).toHaveBeenCalledWith({
libraryId: library.id,
query: '',
types: ['html'],
paginationParams,
}));
});
it('Filters blocks by other types', async () => {
const library = libraryFactory({
blockTypes: [
{ block_type: 'squirrel', display_name: 'Squirrel' },
{ block_type: 'fox', display_name: 'Fox' },
VIDEO_TYPE,
],
});
await render(library, genState(library));
const filter = screen.getByTestId('filter-dropdown');
act(() => {
fireEvent.change(filter, { target: { value: '^' } });
});
await waitFor(() => expect(searchLibrary.fn).toHaveBeenCalledWith({
libraryId: library.id,
query: '',
types: ['squirrel', 'fox'],
paginationParams,
}));
});
it('Commits changes', async () => {
const library = libraryFactory({ has_unpublished_changes: true });
await render(library, genState(library));
screen.getByText('Publish').click();
expect(commitLibraryChanges.fn).toHaveBeenCalledWith({ libraryId: library.id });
});
it('Reverts changes', async () => {
const library = libraryFactory({ has_unpublished_changes: true });
await render(library, genState(library));
screen.getByText('Discard changes').click();
expect(revertLibraryChanges.fn).toHaveBeenCalledWith({
libraryId: library.id,
paginationParams,
});
});
it('Deletes a block', async () => {
const library = libraryFactory();
const block = blockFactory(undefined, { library });
await render(library, genState(library, [block]));
const del = screen.getByLabelText('Delete');
act(() => {
del.click();
});
const yes = await screen.findByText('Yes.');
act(() => {
yes.click();
});
await waitFor(
() => expect(deleteLibraryBlock.fn).toHaveBeenCalledWith({ blockId: block.id }),
);
});
});