UNPKG

@instructure/ui-test-utils

Version:

A UI testing library made by Instructure Inc.

502 lines (501 loc) 17.9 kB
var _svg, _div, _div2, _div3, _div4, _div5, _div6, _div7, _div8, _div9, _div0, _div1, _div10, _div11, _label, _label2, _label3, _input, _button, _fieldset, _span, _div12, _svg2, _div13, _div14, _div15, _form, _form2, _div16, _div17, _button2; /* * The MIT License (MIT) * * Copyright (c) 2015 - present Instructure, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import { findWithLabel, findWithTitle, findWithText, mount, expect, findAll, find, spy, wait, within } from '../index'; import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime"; describe('queries', async () => { it('throws an error message by default when nothing is found', async () => { await expect(findAll('[selected]', { timeout: 0 })).to.be.rejected(); await expect(findAll(':withLabel(pineapple)', { timeout: 0 })).to.be.rejected(); await expect(findAll('pineapple', { timeout: 0 })).to.be.rejected(); await expect(findAll(':withText(pineapple)', { timeout: 0 })).to.be.rejected(); await expect(findAll('table', { timeout: 100 })).to.be.rejected(); }); it('should return empty array when configured to expect empty results', async () => { const options = { expectEmpty: true }; expect(await findAll('[selected]', options)).to.have.length(0); expect(await findAll(':withLabel(pineapple)', options)).to.have.length(0); expect(await findAll('pineapple', options)).to.have.length(0); expect(await findAll(':withText(pineapple)', options)).to.have.length(0); expect(await findAll(':withTitle(pineapple)', options)).to.have.length(0); }); it('works with SVG elements', async () => { await mount(_svg || (_svg = _jsxs("svg", { children: [_jsx("title", { children: "Close" }), _jsx("g", { children: _jsx("path", {}) })] }))); expect(await findAll(':withTitle(Close)')).to.have.length(1); }); describe('by locator', async () => { it('finds a single element', async () => { await mount(_div || (_div = _jsx("div", { "data-uid": "Foo", children: "hello world" }))); expect(await find('[data-uid~="Foo"]')).to.exist(); }); it('finds multiple elements', async () => { await mount(_div2 || (_div2 = _jsxs("div", { children: [_jsx("div", { "data-uid": "Foo", children: "hello world" }), _jsx("div", { "data-uid": "Foo", children: "hello world" }), _jsx("div", { "data-uid": "Bar", children: "hello world" }), _jsx("div", { "data-uid": "Foo", children: "hello world" })] }))); expect(await findAll('[data-uid~="Foo"]')).to.have.length(3); }); it('finds elements with space separated attribute values', async () => { await mount(_div3 || (_div3 = _jsxs("div", { children: [_jsx("div", { "data-uid": "Foo", children: "hello world" }), _jsx("div", { "data-uid": "Foo Bar", children: "hello world" }), _jsx("div", { "data-uid": "Qux Foo Bar Baz", children: "hello world" }), _jsx("div", { "data-uid": "Qux Bar Foo", children: "hello world" })] }))); expect(await findAll('[data-uid~="Foo"]')).to.have.length(4); }); it('does not find elements with attribute values that are substrings', async () => { await mount(_div4 || (_div4 = _jsxs("div", { children: [_jsx("div", { "data-uid": "FooBar", children: "hello world" }), _jsx("div", { "data-uid": "Foooo", children: "hello world" }), _jsx("div", { "data-uid": "FooFooFoo", children: "hello world" }), _jsx("div", { "data-uid": "Baz FooBar QuxFoo Fooo", children: "hello world" })] }))); expect(await findAll('[data-uid~="Foo"]', { expectEmpty: true })).to.have.length(0); }); }); describe('by text', async () => { it('can get elements by matching their text content', async () => { await mount(_div5 || (_div5 = _jsxs("div", { "data-locator": "TestLocator", children: [_jsx("span", { children: "Currently showing: " }), _jsx("span", { children: `Step 1 of 4` })] }))); expect(await findWithText('Currently showing:')).to.exist(); expect(await findAll(':withText("Step 1 of 4")')).to.have.length(1); expect(await findAll(':withText("Currently showing: Step 1 of 4")')).to.have.length(1); }); it('can get elements by matching their nested contents', async () => { await mount(_div6 || (_div6 = _jsx("div", { children: _jsx("span", { children: "Currently showing" }) }))); expect(await findAll(':contains(Currently showing)')).to.have.length(4); // body, div (mount node), div, span }); it('should filter out non-matching results', async () => { await mount(_div7 || (_div7 = _jsx("div", { "data-locator": "TestLocator", children: _jsx("span", { children: "Currently showing" }) }))); expect(await findAll('[data-locator="TestLocator"]:withText(Foo)', { expectEmpty: true })).to.have.length(0); }); it('can get elements by matching their text across adjacent text nodes', async () => { const div = document.createElement('div'); const textNodeContent = ['£', '24', '.', '99']; textNodeContent.map(text => document.createTextNode(text)).forEach(textNode => div.appendChild(textNode)); const subject = await mount(_div8 || (_div8 = _jsx("div", {}))); subject.getDOMNode().appendChild(div); const nodes = await findAll(':withText(£24.99)'); expect(nodes).to.have.length(1); }); it('gets text content correctly', async () => { const subject = await mount(_div9 || (_div9 = _jsx("div", { children: _jsx("span", { children: "Hello World" }) }))); expect(within(subject.getDOMNode())).to.have.text('Hello World'); }); }); describe('by label', async () => { it('can find an input with an aria-labelledby attribute', async () => { await mount(_div0 || (_div0 = _jsxs("div", { children: [_jsx("label", { id: "name-label", children: "Name" }), _jsx("input", { "aria-labelledby": "name-label", id: "name-id" })] }))); expect(await findAll(':withLabel(Name)')).to.have.length(1); expect(await findWithLabel('Name')).to.exist(); }); it('can find an input with a complex aria-labelledby attribute', async () => { await mount(_div1 || (_div1 = _jsxs("div", { children: [_jsx("label", { id: "name-label-one", children: "Name" }), _jsx("span", { id: "name-label-two", children: "(Last, First)" }), _jsx("input", { "aria-labelledby": "name-label-one name-label-two", id: "name-id" })] }))); expect(await findAll(':label(Name)', { exact: false })).to.have.length(1); expect(await findAll(':withLabel("(Last, First)")', { exact: false })).to.have.length(1).to.have.length(1); expect(await findAll(':withLabel("Name (Last, First)")', { exact: false })).to.have.length(1); }); it('can find an input with an id via the `for` attribute', async () => { await mount(_div10 || (_div10 = _jsxs("div", { children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "first.id", children: "First name" }), _jsx("input", { id: "first.id" })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "last-id", children: _jsx("span", { children: "Last name" }) }), _jsx("input", { id: "last-id" })] })] }))); expect(await findAll(':withLabel(First name)')).to.have.length(1); expect(await findAll(':withLabel(Last name)')).to.have.length(1); }); it('can find an input with an id via a for attribute', async () => { await mount(_div11 || (_div11 = _jsxs("div", { children: [_jsx("label", { htmlFor: "name-id", children: "Name" }), _jsx("input", { id: "name-id" })] }))); expect(await findAll(':withLabel(Name)')).to.have.length(1); }); it('can find an input nested in a label', async () => { await mount(_label || (_label = _jsxs("label", { children: ["Name", _jsx("input", {})] }))); expect(await findAll(':withLabel(Name)')).to.have.length(1); }); it('handles a label with no form control', async () => { await mount(_label2 || (_label2 = _jsx("label", { children: "First name" }))); expect(await find(':withLabel(Name)', { expectEmpty: true })).to.be.null(); }); it('handles a totally empty label', async () => { await mount(_label3 || (_label3 = _jsx("label", {}))); expect(await find(':withLabel(" ")', { expectEmpty: true })).to.be.null(); }); it('can find an input with an aria-label', async () => { await mount(_input || (_input = _jsx("input", { "aria-label": "Name" }))); expect(await findAll(':withLabel(Name)')).to.have.length(1); }); it('can find a button by its text content', async () => { await mount(_button || (_button = _jsx("button", { children: "Submit" }))); expect(await findAll(':withLabel(Submit)')).to.have.length(1); }); it('can find a fieldset by its legend', async () => { await mount(_fieldset || (_fieldset = _jsxs("fieldset", { children: [_jsx("legend", { children: "Full name" }), _jsxs("label", { children: ["First name ", _jsx("input", { type: "text" })] })] }))); expect(await findAll(':withLabel(Full name)')).to.have.length(1); }); it('can find an element with a visually hidden label', async () => { await mount(_jsx("button", { children: _jsx("span", { style: { position: 'absolute', left: -9999, top: -9999 }, children: "Hello World" }) })); expect(await find('button:withLabel(Hello World)')).to.exist(); }); it('can find an element with a visually hidden label and a visible label', async () => { await mount(_jsxs("button", { children: [_jsx("span", { style: { position: 'absolute', left: -9999, top: -9999 }, children: "Hello World" }), _span || (_span = _jsx("span", { "aria-hidden": "true", children: "Hello" }))] })); expect(await find('button:withLabel(Hello WorldHello)')).to.exist(); }); }); describe('by title', async () => { it('can find an element by its title', async () => { await mount(_div12 || (_div12 = _jsxs("div", { children: [_jsx("span", { title: "Ignore this", children: "foo" }), _jsx("span", { title: "Delete", children: "bar" }), _jsx("span", { title: "Ignore this as well", children: "baz" })] }))); expect(await findAll(':title(Delete)')).to.have.length(1); expect(await findAll(':withTitle(Ignore)', { exact: false })).to.have.length(2); }); it('can find an SVG element by its title', async () => { await mount(_svg2 || (_svg2 = _jsxs("svg", { children: [_jsx("title", { children: "Close" }), _jsx("g", { children: _jsx("path", {}) })] }))); expect(await findWithTitle('Close')).to.exist(); }); }); describe('by value', async () => { it('can find an element by its value', async () => { await mount(_div13 || (_div13 = _jsxs("div", { children: [_jsx("input", { type: "text" }), _jsx("input", { type: "text", defaultValue: "Norris" }), _jsx("input", { type: "text" })] }))); expect(await findAll('[value="Norris"]')).to.have.length(1); }); }); describe('by attribute', async () => { it('can find an element by attribute', async () => { await mount(_div14 || (_div14 = _jsxs("div", { children: [_jsx("input", { type: "text" }), _jsx("input", { type: "text", defaultValue: "Norris" }), _jsx("input", { type: "text" })] }))); expect(await findAll('input[type]')).to.have.length(3); }); it('can find an element by attribute name and value', async () => { await mount(_div15 || (_div15 = _jsxs("div", { children: [_jsx("input", { type: "text" }), _jsx("input", { type: "password" })] }))); expect(await findAll('input[type="password"]')).to.have.length(1); }); }); describe('findParent', async () => { it('can find a matching parent element', async () => { await mount(_form || (_form = _jsx("form", { children: _jsx("input", { type: "text" }) }))); const input = await find('input'); const form = await input.findParent('form'); expect(form).to.exist(); }); it('includes the element itself', async () => { await mount(_form2 || (_form2 = _jsx("form", { children: _jsx("input", { type: "text" }) }))); const input1 = await find('input'); const input2 = await input1.findParent('input'); expect(input1.getDOMNode()).to.equal(input2.getDOMNode()); }); }); describe('findParents', async () => { it('can find matching parents', async () => { await mount(_div16 || (_div16 = _jsx("div", { "data-foo": "bar", children: _jsx("div", { children: _jsx("div", { "data-foo": "baz", children: _jsx("input", { type: "text" }) }) }) }))); const input = await find('input'); const parents = await input.findParents('[data-foo]'); expect(parents.length).to.equal(2); expect(parents[1].getAttribute('data-foo')).to.equal('bar'); }); it('includes the element itself', async () => { await mount(_div17 || (_div17 = _jsx("div", { "data-foo": "bar", children: _jsx("div", { children: _jsx("div", { "data-foo": "baz", children: _jsx("input", { type: "text", "data-foo": "first" }) }) }) }))); const input = await find('input'); const parents = await input.findParents('[data-foo]'); expect(parents.length).to.equal(3); expect(parents[0].getAttribute('data-foo')).to.equal('first'); }); }); describe('event helpers', async () => { describe('#focus', async () => { it('should programmtically move focus', async () => { await mount(_button2 || (_button2 = _jsx("button", { children: "hello" }))); const button = await find('button'); await button.focus(); expect(button.focused()).to.be.true(); }); it('should support initializing the event object', async () => { const handleFocus = spy(e => { e.persist(); // so that we can get the native event later }); await mount(_jsx("button", { onFocus: handleFocus, children: "hello" })); const button = await find('button'); await button.focusIn({ bubbles: true }); const nativeEvent = handleFocus.getCall(0).args[0].nativeEvent; expect(nativeEvent.bubbles).to.be.true(); }); }); describe('#click', async () => { it('should support spies on event methods', async () => { const handleClick = spy(e => { e.persist(); // so that we can get the native event later e.preventDefault(); }); const subject = await mount(_jsx("button", { onClick: handleClick, children: "hello" })); const button = within(subject.getDOMNode()); const event = await button.click({}); await wait(() => { expect(event.preventDefault).to.have.been.calledOnce(); }); }); }); }); });