乐趣区

关于css:css选择器的使用

前言

这周始终在写数据校验,前台单元测试的时候,有时候 v 层没有渲染出数据,这时就须要手动让他渲染。

it('should create', () => 
    // 如下断言保障了组件在初始化的过程中未产生异样
    expect(component).toBeTruthy();

    // 模仿生产环境后盾异步返回数据 
    getTestScheduler().flush();

    // 保障接管模仿数据后,组件从新渲染未产生异样
    fixture.detectChanges();});

咱们能够从潘老师的博客中明确语句的具体含意。然而这还是不够,咱们最终确认 v 层数据渲染了与否还是通过咱们肉眼判断的,这就失去了单元测试的意义。为了进一步欠缺,咱们还须要在单元测试中退出断言,断言以后 v 层胜利渲染了数据。

css 选择器

要断言以后 v 层的某一项胜利渲染了数据,首先要获取这个 v 层元素。学习的教程中也有通过 table 元素和 input 元素断言的实例。然而我这里获取的是一个 div 里的值。具体 v 层代码如下

<div class="row">
  <div class="col-md-2 text-right">
    <label> 科目 </label>
  </div>
  <div class="col-md-8">
    {{subject.course?.name}}
  </div>
</div>

咱们想要断言 subject.course.name 的值。然而这是一个一般的 div,没有什么非凡的属性。这时我就想趁此机会理解一下 css 选择器。
css 选择器能够通过多种形式来获取一个 v 层的元素,介绍几种罕用的。
一、相对定位

const nameInput: HTMLInputElement = fixture.debugElement.query(By.css('"html >  
body > div > div > form > input')).nativeElement;

这种定位就是通过一层一层的父子元素关系来找到某一元素,长处是能够精确地找到某一元素。然而,一旦 v 层相干的元素扭转,这里也要跟着变。

二、绝对定位
了解了相对定位,绝对定位也就好了解了。

const nameInput: HTMLInputElement = fixture.debugElement.query(By.css('"div > table')).nativeElement;

他会匹配所有在某个 div 下的 table 元素。

三、属性定位

属性定位又能够分为 id 定位,class 定位和(其余)属性定位。咱们在实例中用的就是属性定位。

const nameInput: HTMLInputElement = fixture.debugElement.query(By.css('input[name="name"]')).nativeElement;

expect(nameInput.value).toEqual(student.name);

这里咱们就是在匹配一个 input 元素,且此 input 的 name 属性为 name。
具体能够看这篇文章:CSS 选择器

应用控制台取得 css 选择器

咱们也能够应用控制台打印某一元素的地位。

找到这个元素,右键 copy,有 copy selector 选项,让咱们看看打印进去了什么

#root0 > div:nth-child(1) > div.col-md-8

找到了元素地位,剩下的断言就很好写了。
然而也遇到了点问题。

我先用的实例的代码

const subjectCourseNameDiv: HTMLDivElement = fixture.debugElement.query(By.css('#root0 > div:nth-child(1) > div.col-md-8')).nativeElement;

expect(subjectCourseNameDiv.value).toContain('科目名称');

然而断言总是过不去,说我断言的值为 undefined。然而对 subjectCourseNameDiv 进行打印获取到的元素也没有问题。

这时我想到了 input 与 div 的不必,咱们 input 是获取的属性的值比方要这样写

<input type=""name="" value="科目名称 XXXX">

而 div 这么写

<div> 科目名称 XXXX</div>

一个是属性,一个是外面的值。而后去网上查一查 div 选择器的写法,不应该是 subjectCourseNameDiv.value,而是subjectCourseNameDiv.innerText
整体代码如下。

fit('should create', () => {expect(component).toBeTruthy();

    const subjectCourseNameDiv: HTMLDivElement = fixture.debugElement.query(By.css('#root0 > div:nth-child(1) > div.col-md-8')).nativeElement;
    expect(subjectCourseNameDiv.innerText).toBe('');

    getTestScheduler().flush();
    fixture.autoDetectChanges();

    expect(subjectCourseNameDiv.innerText).toContain('科目名称');
  });

跑一遍单元测试,胜利通过。快乐地提交代码。然而事件没有那么简略。

机器人测试过不去,我整体跑一遍单元测试,却在刚刚写的单元测试上报错,说没有找到对应元素。

我再独自跑这个单元测试,

测试通过。。。

考虑一番后,猜想可能因为整体单元测试 v 层扭转,导致找不到元素了。
咱们要晓得有什么变动。

打印一下这个的 selector.

#root158 > div

这个数字是 158,应该代表测试的接点数。这样咱们写的必定不对,这时咱们能够应用绝对定位。删除#root0 >.

const subjectCourseNameDiv: HTMLInputElement = fixture.debugElement.query(By.css('div:nth-child(1) > div.col-md-8')).nativeElement;

单元测试通过。

总结

css 选择器让我感觉到了 html 的对象化。原来刚学的时候总以为 html 与后端语言语法齐全不一样。然而其实实质是一样的。这应该就是为什么学一种语言而通全副吧。

退出移动版