赛普拉斯测试伪CSS类:before

Cypress testing pseudo CSS class :before

提问人:physicsboy 提问时间:4/4/2019 更新时间:1/24/2020 访问量:14607

问:

有没有办法让我在 Cypress 的元素上测试伪 CSS 类的 :before?content

我看到的链接记录了:

但是我没有找到任何使用伪类的CSS类。::before

想象一下代码:

.myClass:before {
  content: "foo-";
}
<div>
  <span class="myClass">Bar</span>
</div>

如何测试“foo-”是否存在?

CSS 集成-测试 赛普拉斯

评论


答:

32赞 Zach Bloomquist 4/4/2019 #1

有一种方法可以断言伪元素的 CSS 属性,尽管它并不像仅仅使用 Cypress 命令那么简单。

  1. 用于获取对元素的引用。cy.get()
  2. 从元素中读取对象,然后调用 Window.getComputedStyle(),它可以读取伪选择器的计算 CSS。Window
  3. 在返回的 CSS 声明上使用 getPropertyValue 来读取属性的值。content
  4. 断言它。

下面是一个适用于 OP 中发布的代码的示例:

cy.get('.myClass')
.then($els => {
  // get Window reference from element
  const win = $els[0].ownerDocument.defaultView
  // use getComputedStyle to read the pseudo selector
  const before = win.getComputedStyle($els[0], 'before')
  // read the value of the `content` CSS property
  const contentValue = before.getPropertyValue('content')
  // the returned value will have double quotes around it, but this is correct
  expect(contentValue).to.eq('"foo-"')
})

评论

1赞 RiZKiT 2/2/2022
我遇到了它在Firefox中不起作用的问题。解决方案似乎是使用 代替 ,这似乎也适用于 chrome。:beforebefore
0赞 kuceb 4/4/2019 #2

尝试对父级的文本进行断言:

cy.get('.myClass').parent().should('have.text', 'foo-bar')

如果这不起作用,您可能需要使用该属性:textContent

cy.get('.myClass').parent(). should($el => expect ($el).to.contain('foo-bar')
)

评论

2赞 Zach Bloomquist 4/4/2019
似乎不起作用,这两个方法最终都会超时expected \n Bar\n to include foo-Bar
17赞 Víctor Navarro 7/29/2019 #3

根据 Zach 的回答,我创建了一个返回伪元素属性的命令(周围没有单引号)。

function unquote(str) {
    return str.replace(/(^")|("$)/g, '');
}

Cypress.Commands.add(
    'before',
    {
        prevSubject: 'element',
    },
    (el, property) => {
        const win = el[0].ownerDocument.defaultView;
        const before = win.getComputedStyle(el[0], 'before');
        return unquote(before.getPropertyValue(property));
    },
);

您将像这样使用它

it('color is black', () => {
    cy.get('button')
       .before('color')
       .should('eq', 'rgb(0,0,0)'); // Or .then()
});

评论

0赞 MatthewLee 1/25/2023
这似乎很流畅,但是当我尝试实现它时,它给了我一个错误,说“之前”需要 2 个参数,但只得到了一个。这些命令确实显示了正在传递的 2 个参数(el 和 property),但似乎“prevSubject”应该允许它在 cy.get 中选择先前选择的元素。有什么想法吗?谢谢!
0赞 Sérgio Junior 1/24/2020 #4

这是我获取、转换和比较十六进制与返回的 rgb 的解决方案。background-color

const RGBToHex = (rgbColor) => {
  // it parse rgb(255, 13, 200) to #fa92D4
  const [red, green, blue] = rgbColor.replace(/[a-z]|\(|\)|\s/g, '').split(',');
  let r = parseInt(red, 10).toString(16);
  let g = parseInt(green, 10).toString(16);
  let b = parseInt(blue, 10).toString(16);

  if (r.length === 1) r = `0${r}`;
  if (g.length === 1) g = `0${g}`;
  if (b.length === 1) b = `0${b}`;

  return `#${r}${g}${b}`;
};


cy.get('.element').then(($el) => {
  const win = $el[0].ownerDocument.defaultView;
  const before = win.getComputedStyle($el[0], 'before');
  const bgColor = before.getPropertyValue('background-color');
  expect(RGBToHex(bgColor)).to.eq('#HEXA');
});