Javascript &引用;未能执行';查询选择器';在';文件';:';类MyComponent扩展HtmleElement“;在业力测试期间

Javascript &引用;未能执行';查询选择器';在';文件';:';类MyComponent扩展HtmleElement“;在业力测试期间,javascript,html,karma-jasmine,web-component,Javascript,Html,Karma Jasmine,Web Component,我得到了这个问题中提到的错误。我不明白为什么我不能检查某些div id是否可用。这是很简单的检查 测试: 测试工具: export class TestUtils { /** * Renders a given element with provided attributes * and returns a promise which resolves as soon as * rendered element becomes available.

我得到了这个问题中提到的错误。我不明白为什么我不能检查某些div id是否可用。这是很简单的检查

测试:

测试工具:

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();
      });
    }
  }
导出类TestUtils{
/**
*使用提供的属性呈现给定元素
*并返回一个承诺,该承诺将尽快解决
*渲染元素变为可用。
*@param{string}标记
*@param{object}属性
*@returns{Promise}
*/
静态呈现(标记,属性={}){
TestUtils.\u renderToDocument(标记、属性);
返回TestUtils.\u waitForComponentToRender(标签);
}
/**
*用提供的元素替换文档的正文
*包括给定的属性。
*@param{string}标记
*@param{object}属性
*/
静态渲染文档(标记、属性){
常量HtmlatAttributes=TestUtils.\u映射对象到HtmlatAttributes(属性);
document.body.innerHTML=`;
}
/**
*将对象转换为属性的HTML字符串表示形式。
*
*例如:`foo:bar',baz:foo}`
*变成'foo=“bar”baz=“foo”`
*
*@param{object}属性
*@返回{string}
*/
静态映射对象HTMLATTRIBUTES(属性){
返回Object.entries(attributes).reduce((上一个,当前)=>{
返回previous+`${current[0]}=“${current[1]}`;
}, "");
}
/**
*返回一个承诺,该承诺将在
*请求的元素变为可用。
*@param{string}标记
*@returns{Promise}
*/
静态异步\u waitForComponentToRender(标记){
返回新承诺(解决=>{
函数requestComponent(){
const元素=document.querySelector(标记);
if(元素){
决心(要素);
}否则{
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);
const templateString=`你好,世界

`; const template=document.createElement(“模板”); template.innerHTML=templateString; 导出类MyComponent扩展HtmleElement{ 构造函数(){ 超级(); const shadowRoot=this.attachShadow({mode:“open”}); appendChild(template.content.cloneNode(true)); } } 定义(“我的组件”,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.
@test C:\\u d\WSs\basic vanilla webcomponent
>因果报应
15 07 2019 18:47:18.412:INFO[卡玛服务器]:卡玛v4.2.0服务器于启动http://0.0.0.0:9876/
15 07 2019 18:47:18.418:INFO[launcher]:启动浏览器Chrome,并发不受限制
15 07 2019 18:47:18.427:信息[启动器]:启动浏览器Chrome
15 07 2019 18:47:21.648:信息[Chrome 75.0.3770(Windows 10.0.0)]:连接到id为99414473的y_r0bher4fnuaibyaaa插座上
简单测试
×首次试验
错误:未能对“文档”执行“querySelector”:“类MyComponent扩展HtmleElement”{
构造函数(){
超级();
const shadowRoot=this.attachShadow({mode:“open”});
appendChild(template.content.cloneNode(true));
}
}'不是有效的选择器。
错误属性:对象({INDEX\u SIZE\u ERR:1,DOMSTRING\u SIZE\u ERR:2,层次结构\u请求\u ERR:3,错误文档\u ERR:4,无效字符\u ERR:5,不允许数据\u ERR:6,不允许修改\u ERR:7,未找到\u ERR:8,不支持\u ERR:9,使用\u属性\u ERR:10,无效状态\u ERR:11,语法\u ERR:12,无效修改\u ERR:13,无效命名空间\u ERR:14,无效访问错误:15、验证错误:16、类型错误:17、安全错误:18、网络错误:19、中止错误:20、URL错误:21、配额错误:22、超时错误:23、无效节点错误:24、数据克隆错误:25、代码:12)
at请求组件(test/test-utils.js:50:36)
at test/test-utils.js:57:9
在
at函数。\ u waitForComponentToRender(test/test-utils.js:48:14)
在Function.render(test/test-utils.js:12:24)
在UserContext上。(test/mycomponent.test.js:6:44)
在
Chrome 75.0.3770(Windows 10.0.0):执行1/1(1失败)错误(0.032秒/0.005秒)
npm ERR!测试失败。有关详细信息,请参阅上文。

TestUtils.render方法接受一个标记(字符串)作为其第一个参数,但在您的代码中传递的是
MyComponent
。这是导致错误的直接原因


尝试调用
TestUtils.render('my-component');
(假设
my-component
MyComponent
的正确标记)。

TestUtils.render方法接受标记(字符串)作为它的第一个参数,但在您的代码中,您正在传入MyComponent。这是错误的直接原因。@Collierre以及如何测试它是否被呈现?例如,假设我想在启动服务器时获取div,它将恰好是document.querySelector('my-component')。shadowRoot.getElementById('mydiv'))。当uint测试它时,我如何做同样的事情,然后我可以检查是否有一个名为mydiv的div,这将是尽可能最简单的单元测试(只需检查它是否被呈现)。您可以调用
TestUtils.render('my-component');
?(假设我的组件是MyComponent的正确标记)谢谢,现在已经修好了!请,如果你已经习惯了对网络组件进行单元测试,你能提供这个答案和一些建议吗?我从中得到的测试工具,我很感兴趣,因为这不依赖于库(好吧,现在这是我的主要目标,学习如何编写和测试普通网络组件)。您将在@Collierre中找到我的全部学习代码。请将您的最后评论作为答案,以便我可以选择作为我问题的最终答案
> @ 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.