@instructure/ui-test-utils
Version:
A UI testing library made by Instructure Inc.
503 lines (502 loc) • 21 kB
JavaScript
"use strict";
var _index = require("../index");
var _jsxRuntime = require("@emotion/react/jsx-runtime");
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.
*/
describe('queries', async () => {
it('throws an error message by default when nothing is found', async () => {
await (0, _index.expect)((0, _index.findAll)('[selected]', {
timeout: 0
})).to.be.rejected();
await (0, _index.expect)((0, _index.findAll)(':withLabel(pineapple)', {
timeout: 0
})).to.be.rejected();
await (0, _index.expect)((0, _index.findAll)('pineapple', {
timeout: 0
})).to.be.rejected();
await (0, _index.expect)((0, _index.findAll)(':withText(pineapple)', {
timeout: 0
})).to.be.rejected();
await (0, _index.expect)((0, _index.findAll)('table', {
timeout: 100
})).to.be.rejected();
});
it('should return empty array when configured to expect empty results', async () => {
const options = {
expectEmpty: true
};
(0, _index.expect)(await (0, _index.findAll)('[selected]', options)).to.have.length(0);
(0, _index.expect)(await (0, _index.findAll)(':withLabel(pineapple)', options)).to.have.length(0);
(0, _index.expect)(await (0, _index.findAll)('pineapple', options)).to.have.length(0);
(0, _index.expect)(await (0, _index.findAll)(':withText(pineapple)', options)).to.have.length(0);
(0, _index.expect)(await (0, _index.findAll)(':withTitle(pineapple)', options)).to.have.length(0);
});
it('works with SVG elements', async () => {
await (0, _index.mount)(_svg || (_svg = (0, _jsxRuntime.jsxs)("svg", {
children: [(0, _jsxRuntime.jsx)("title", {
children: "Close"
}), (0, _jsxRuntime.jsx)("g", {
children: (0, _jsxRuntime.jsx)("path", {})
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':withTitle(Close)')).to.have.length(1);
});
describe('by locator', async () => {
it('finds a single element', async () => {
await (0, _index.mount)(_div || (_div = (0, _jsxRuntime.jsx)("div", {
"data-uid": "Foo",
children: "hello world"
})));
(0, _index.expect)(await (0, _index.find)('[data-uid~="Foo"]')).to.exist();
});
it('finds multiple elements', async () => {
await (0, _index.mount)(_div2 || (_div2 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("div", {
"data-uid": "Foo",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Foo",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Bar",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Foo",
children: "hello world"
})]
})));
(0, _index.expect)(await (0, _index.findAll)('[data-uid~="Foo"]')).to.have.length(3);
});
it('finds elements with space separated attribute values', async () => {
await (0, _index.mount)(_div3 || (_div3 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("div", {
"data-uid": "Foo",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Foo Bar",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Qux Foo Bar Baz",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Qux Bar Foo",
children: "hello world"
})]
})));
(0, _index.expect)(await (0, _index.findAll)('[data-uid~="Foo"]')).to.have.length(4);
});
it('does not find elements with attribute values that are substrings', async () => {
await (0, _index.mount)(_div4 || (_div4 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("div", {
"data-uid": "FooBar",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Foooo",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "FooFooFoo",
children: "hello world"
}), (0, _jsxRuntime.jsx)("div", {
"data-uid": "Baz FooBar QuxFoo Fooo",
children: "hello world"
})]
})));
(0, _index.expect)(await (0, _index.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 (0, _index.mount)(_div5 || (_div5 = (0, _jsxRuntime.jsxs)("div", {
"data-locator": "TestLocator",
children: [(0, _jsxRuntime.jsx)("span", {
children: "Currently showing: "
}), (0, _jsxRuntime.jsx)("span", {
children: `Step
1
of 4`
})]
})));
(0, _index.expect)(await (0, _index.findWithText)('Currently showing:')).to.exist();
(0, _index.expect)(await (0, _index.findAll)(':withText("Step 1 of 4")')).to.have.length(1);
(0, _index.expect)(await (0, _index.findAll)(':withText("Currently showing: Step 1 of 4")')).to.have.length(1);
});
it('can get elements by matching their nested contents', async () => {
await (0, _index.mount)(_div6 || (_div6 = (0, _jsxRuntime.jsx)("div", {
children: (0, _jsxRuntime.jsx)("span", {
children: "Currently showing"
})
})));
(0, _index.expect)(await (0, _index.findAll)(':contains(Currently showing)')).to.have.length(4); // body, div (mount node), div, span
});
it('should filter out non-matching results', async () => {
await (0, _index.mount)(_div7 || (_div7 = (0, _jsxRuntime.jsx)("div", {
"data-locator": "TestLocator",
children: (0, _jsxRuntime.jsx)("span", {
children: "Currently showing"
})
})));
(0, _index.expect)(await (0, _index.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 (0, _index.mount)(_div8 || (_div8 = (0, _jsxRuntime.jsx)("div", {})));
subject.getDOMNode().appendChild(div);
const nodes = await (0, _index.findAll)(':withText(£24.99)');
(0, _index.expect)(nodes).to.have.length(1);
});
it('gets text content correctly', async () => {
const subject = await (0, _index.mount)(_div9 || (_div9 = (0, _jsxRuntime.jsx)("div", {
children: (0, _jsxRuntime.jsx)("span", {
children: "Hello World"
})
})));
(0, _index.expect)((0, _index.within)(subject.getDOMNode())).to.have.text('Hello World');
});
});
describe('by label', async () => {
it('can find an input with an aria-labelledby attribute', async () => {
await (0, _index.mount)(_div0 || (_div0 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("label", {
id: "name-label",
children: "Name"
}), (0, _jsxRuntime.jsx)("input", {
"aria-labelledby": "name-label",
id: "name-id"
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Name)')).to.have.length(1);
(0, _index.expect)(await (0, _index.findWithLabel)('Name')).to.exist();
});
it('can find an input with a complex aria-labelledby attribute', async () => {
await (0, _index.mount)(_div1 || (_div1 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("label", {
id: "name-label-one",
children: "Name"
}), (0, _jsxRuntime.jsx)("span", {
id: "name-label-two",
children: "(Last, First)"
}), (0, _jsxRuntime.jsx)("input", {
"aria-labelledby": "name-label-one name-label-two",
id: "name-id"
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':label(Name)', {
exact: false
})).to.have.length(1);
(0, _index.expect)(await (0, _index.findAll)(':withLabel("(Last, First)")', {
exact: false
})).to.have.length(1).to.have.length(1);
(0, _index.expect)(await (0, _index.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 (0, _index.mount)(_div10 || (_div10 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("label", {
htmlFor: "first.id",
children: "First name"
}), (0, _jsxRuntime.jsx)("input", {
id: "first.id"
})]
}), (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("label", {
htmlFor: "last-id",
children: (0, _jsxRuntime.jsx)("span", {
children: "Last name"
})
}), (0, _jsxRuntime.jsx)("input", {
id: "last-id"
})]
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(First name)')).to.have.length(1);
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Last name)')).to.have.length(1);
});
it('can find an input with an id via a for attribute', async () => {
await (0, _index.mount)(_div11 || (_div11 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("label", {
htmlFor: "name-id",
children: "Name"
}), (0, _jsxRuntime.jsx)("input", {
id: "name-id"
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Name)')).to.have.length(1);
});
it('can find an input nested in a label', async () => {
await (0, _index.mount)(_label || (_label = (0, _jsxRuntime.jsxs)("label", {
children: ["Name", (0, _jsxRuntime.jsx)("input", {})]
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Name)')).to.have.length(1);
});
it('handles a label with no form control', async () => {
await (0, _index.mount)(_label2 || (_label2 = (0, _jsxRuntime.jsx)("label", {
children: "First name"
})));
(0, _index.expect)(await (0, _index.find)(':withLabel(Name)', {
expectEmpty: true
})).to.be.null();
});
it('handles a totally empty label', async () => {
await (0, _index.mount)(_label3 || (_label3 = (0, _jsxRuntime.jsx)("label", {})));
(0, _index.expect)(await (0, _index.find)(':withLabel(" ")', {
expectEmpty: true
})).to.be.null();
});
it('can find an input with an aria-label', async () => {
await (0, _index.mount)(_input || (_input = (0, _jsxRuntime.jsx)("input", {
"aria-label": "Name"
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Name)')).to.have.length(1);
});
it('can find a button by its text content', async () => {
await (0, _index.mount)(_button || (_button = (0, _jsxRuntime.jsx)("button", {
children: "Submit"
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Submit)')).to.have.length(1);
});
it('can find a fieldset by its legend', async () => {
await (0, _index.mount)(_fieldset || (_fieldset = (0, _jsxRuntime.jsxs)("fieldset", {
children: [(0, _jsxRuntime.jsx)("legend", {
children: "Full name"
}), (0, _jsxRuntime.jsxs)("label", {
children: ["First name ", (0, _jsxRuntime.jsx)("input", {
type: "text"
})]
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':withLabel(Full name)')).to.have.length(1);
});
it('can find an element with a visually hidden label', async () => {
await (0, _index.mount)((0, _jsxRuntime.jsx)("button", {
children: (0, _jsxRuntime.jsx)("span", {
style: {
position: 'absolute',
left: -9999,
top: -9999
},
children: "Hello World"
})
}));
(0, _index.expect)(await (0, _index.find)('button:withLabel(Hello World)')).to.exist();
});
it('can find an element with a visually hidden label and a visible label', async () => {
await (0, _index.mount)((0, _jsxRuntime.jsxs)("button", {
children: [(0, _jsxRuntime.jsx)("span", {
style: {
position: 'absolute',
left: -9999,
top: -9999
},
children: "Hello World"
}), _span || (_span = (0, _jsxRuntime.jsx)("span", {
"aria-hidden": "true",
children: "Hello"
}))]
}));
(0, _index.expect)(await (0, _index.find)('button:withLabel(Hello WorldHello)')).to.exist();
});
});
describe('by title', async () => {
it('can find an element by its title', async () => {
await (0, _index.mount)(_div12 || (_div12 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("span", {
title: "Ignore this",
children: "foo"
}), (0, _jsxRuntime.jsx)("span", {
title: "Delete",
children: "bar"
}), (0, _jsxRuntime.jsx)("span", {
title: "Ignore this as well",
children: "baz"
})]
})));
(0, _index.expect)(await (0, _index.findAll)(':title(Delete)')).to.have.length(1);
(0, _index.expect)(await (0, _index.findAll)(':withTitle(Ignore)', {
exact: false
})).to.have.length(2);
});
it('can find an SVG element by its title', async () => {
await (0, _index.mount)(_svg2 || (_svg2 = (0, _jsxRuntime.jsxs)("svg", {
children: [(0, _jsxRuntime.jsx)("title", {
children: "Close"
}), (0, _jsxRuntime.jsx)("g", {
children: (0, _jsxRuntime.jsx)("path", {})
})]
})));
(0, _index.expect)(await (0, _index.findWithTitle)('Close')).to.exist();
});
});
describe('by value', async () => {
it('can find an element by its value', async () => {
await (0, _index.mount)(_div13 || (_div13 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("input", {
type: "text"
}), (0, _jsxRuntime.jsx)("input", {
type: "text",
defaultValue: "Norris"
}), (0, _jsxRuntime.jsx)("input", {
type: "text"
})]
})));
(0, _index.expect)(await (0, _index.findAll)('[value="Norris"]')).to.have.length(1);
});
});
describe('by attribute', async () => {
it('can find an element by attribute', async () => {
await (0, _index.mount)(_div14 || (_div14 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("input", {
type: "text"
}), (0, _jsxRuntime.jsx)("input", {
type: "text",
defaultValue: "Norris"
}), (0, _jsxRuntime.jsx)("input", {
type: "text"
})]
})));
(0, _index.expect)(await (0, _index.findAll)('input[type]')).to.have.length(3);
});
it('can find an element by attribute name and value', async () => {
await (0, _index.mount)(_div15 || (_div15 = (0, _jsxRuntime.jsxs)("div", {
children: [(0, _jsxRuntime.jsx)("input", {
type: "text"
}), (0, _jsxRuntime.jsx)("input", {
type: "password"
})]
})));
(0, _index.expect)(await (0, _index.findAll)('input[type="password"]')).to.have.length(1);
});
});
describe('findParent', async () => {
it('can find a matching parent element', async () => {
await (0, _index.mount)(_form || (_form = (0, _jsxRuntime.jsx)("form", {
children: (0, _jsxRuntime.jsx)("input", {
type: "text"
})
})));
const input = await (0, _index.find)('input');
const form = await input.findParent('form');
(0, _index.expect)(form).to.exist();
});
it('includes the element itself', async () => {
await (0, _index.mount)(_form2 || (_form2 = (0, _jsxRuntime.jsx)("form", {
children: (0, _jsxRuntime.jsx)("input", {
type: "text"
})
})));
const input1 = await (0, _index.find)('input');
const input2 = await input1.findParent('input');
(0, _index.expect)(input1.getDOMNode()).to.equal(input2.getDOMNode());
});
});
describe('findParents', async () => {
it('can find matching parents', async () => {
await (0, _index.mount)(_div16 || (_div16 = (0, _jsxRuntime.jsx)("div", {
"data-foo": "bar",
children: (0, _jsxRuntime.jsx)("div", {
children: (0, _jsxRuntime.jsx)("div", {
"data-foo": "baz",
children: (0, _jsxRuntime.jsx)("input", {
type: "text"
})
})
})
})));
const input = await (0, _index.find)('input');
const parents = await input.findParents('[data-foo]');
(0, _index.expect)(parents.length).to.equal(2);
(0, _index.expect)(parents[1].getAttribute('data-foo')).to.equal('bar');
});
it('includes the element itself', async () => {
await (0, _index.mount)(_div17 || (_div17 = (0, _jsxRuntime.jsx)("div", {
"data-foo": "bar",
children: (0, _jsxRuntime.jsx)("div", {
children: (0, _jsxRuntime.jsx)("div", {
"data-foo": "baz",
children: (0, _jsxRuntime.jsx)("input", {
type: "text",
"data-foo": "first"
})
})
})
})));
const input = await (0, _index.find)('input');
const parents = await input.findParents('[data-foo]');
(0, _index.expect)(parents.length).to.equal(3);
(0, _index.expect)(parents[0].getAttribute('data-foo')).to.equal('first');
});
});
describe('event helpers', async () => {
describe('#focus', async () => {
it('should programmtically move focus', async () => {
await (0, _index.mount)(_button2 || (_button2 = (0, _jsxRuntime.jsx)("button", {
children: "hello"
})));
const button = await (0, _index.find)('button');
await button.focus();
(0, _index.expect)(button.focused()).to.be.true();
});
it('should support initializing the event object', async () => {
const handleFocus = (0, _index.spy)(e => {
e.persist(); // so that we can get the native event later
});
await (0, _index.mount)((0, _jsxRuntime.jsx)("button", {
onFocus: handleFocus,
children: "hello"
}));
const button = await (0, _index.find)('button');
await button.focusIn({
bubbles: true
});
const nativeEvent = handleFocus.getCall(0).args[0].nativeEvent;
(0, _index.expect)(nativeEvent.bubbles).to.be.true();
});
});
describe('#click', async () => {
it('should support spies on event methods', async () => {
const handleClick = (0, _index.spy)(e => {
e.persist(); // so that we can get the native event later
e.preventDefault();
});
const subject = await (0, _index.mount)((0, _jsxRuntime.jsx)("button", {
onClick: handleClick,
children: "hello"
}));
const button = (0, _index.within)(subject.getDOMNode());
const event = await button.click({});
await (0, _index.wait)(() => {
(0, _index.expect)(event.preventDefault).to.have.been.calledOnce();
});
});
});
});
});