我遇到了这个问题标题中提到的错误。我不明白为什么我无法检查某些div ID是否可用。这很简单。
测试:
import { MyComponent } from "../src/my-component.js";
import { TestUtils } from "./test-utils.js";
describe("simple test", () => {
it("first test", async () => {
const { shadowRoot } = await TestUtils.render(MyComponent);
expect(shadowRoot.querySelector("#mydiv")).toBeTruthy();
});
});
testUtils:
export class TestUtils {
/**
* Renders a given element with provided attributes
* and returns a promise which resolves as soon as
* rendered element becomes available.
* @param {string} tag
* @param {object} attributes
* @returns {Promise<HTMLElement>}
*/
static render(tag, attributes = {}) {
TestUtils._renderToDocument(tag, attributes);
return TestUtils._waitForComponentToRender(tag);
}
/**
* Replaces document's body with provided element
* including given attributes.
* @param {string} tag
* @param {object} attributes
*/
static _renderToDocument(tag, attributes) {
const htmlAttributes = TestUtils._mapObjectToHTMLAttributes(attributes);
document.body.innerHTML = `<${tag} ${htmlAttributes}></${tag}>`;
}
/**
* Converts an object to HTML string representation of attributes.
*
* For example: `{ foo: "bar", baz: "foo" }`
* becomes `foo="bar" baz="foo"`
*
* @param {object} attributes
* @returns {string}
*/
static _mapObjectToHTMLAttributes(attributes) {
return Object.entries(attributes).reduce((previous, current) => {
return previous + ` ${current[0]}="${current[1]}"`;
}, "");
}
/**
* Returns a promise which resolves as soon as
* requested element becomes available.
* @param {string} tag
* @returns {Promise<HTMLElement>}
*/
static async _waitForComponentToRender(tag) {
return new Promise(resolve => {
function requestComponent() {
const element = document.querySelector(tag);
if (element) {
resolve(element);
} else {
window.requestAnimationFrame(requestComponent);
}
}
requestComponent();
});
}
}
组件:
const templateString = `<div id="mydiv"><p>Hello world!</p></div>`;
const template = document.createElement("template");
template.innerHTML = templateString;
export class MyComponent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(template.content.cloneNode(true));
}
}
customElements.define("my-component", MyComponent);
完整日志:
> @ test C:\_d\WSs\basic-vanilla-webcomponent
> karma start
15 07 2019 18:47:18.412:INFO [karma-server]: Karma v4.2.0 server started at http://0.0.0.0:9876/
15 07 2019 18:47:18.418:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
15 07 2019 18:47:18.427:INFO [launcher]: Starting browser Chrome
15 07 2019 18:47:21.648:INFO [Chrome 75.0.3770 (Windows 10.0.0)]: Connected on socket y_r0BhEr4FNUaiByAAAA with id 99414473
simple test
× first test
Error: Failed to execute 'querySelector' on 'Document': 'class MyComponent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(template.content.cloneNode(true));
}
}' is not a valid selector.
error properties: Object({ INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, NO_DATA_ALLOWED_ERR: 6, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INUSE_ATTRIBUTE_ERR: 10, INVALID_STATE_ERR: 11, SYNTAX_ERR: 12, INVALID_MODIFICATION_ERR: 13, NAMESPACE_ERR: 14, INVALID_ACCESS_ERR: 15, VALIDATION_ERR: 16, TYPE_MISMATCH_ERR: 17, SECURITY_ERR: 18, NETWORK_ERR: 19, ABORT_ERR: 20, URL_MISMATCH_ERR: 21, QUOTA_EXCEEDED_ERR: 22, TIMEOUT_ERR: 23, INVALID_NODE_TYPE_ERR: 24, DATA_CLONE_ERR: 25, code: 12 })
at requestComponent (test/test-utils.js:50:36)
at test/test-utils.js:57:9
at <Jasmine>
at Function._waitForComponentToRender (test/test-utils.js:48:14)
at Function.render (test/test-utils.js:12:24)
at UserContext.<anonymous> (test/my-component.test.js:6:44)
at <Jasmine>
Chrome 75.0.3770 (Windows 10.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.032 secs / 0.005 secs)
npm ERR! Test failed. See above for more details.
答案 0 :(得分:1)
TestUtils.render
方法接受标记(字符串)作为其第一个参数,但是在您的代码中您传入了MyComponent
。这是错误的直接原因。
尝试调用TestUtils.render('my-component');
(假设my-component
是MyComponent
的正确标记)。