测试链接样式更改

时间:2015-03-03 22:03:42

标签: css testing selenium protractor end-to-end

在我们的一个测试中,我们正在测试鼠标悬停在之后的链接(a元素)样式更改。

默认情况下,链接的黑色字体没有装饰,但鼠标悬停在字体上会变为蓝色,链接文本会加下划线。以下是相关测试:

it("should change font style on mouse over", function () {
    expect(scope.page.forgotPassword.getCssValue("color")).toEqual("rgba(11, 51, 60, 1)");
    expect(scope.page.forgotPassword.getCssValue("text-decoration")).toEqual("none");

    browser.actions().mouseMove(scope.page.forgotPassword).perform();

    expect(scope.page.forgotPassword.getCssValue("color")).toEqual("rgba(42, 100, 150, 1)");
    expect(scope.page.forgotPassword.getCssValue("text-decoration")).toEqual("underline");
});

问题在于,在大约十分之一的运行中,它失败并显示以下错误消息:

  

预计'rgba(11,51,60,1)'等于'rgba(42,100,150,1)'。

     

期望'none'等于'强调'。

我怀疑它在实际更改之前会读取css样式。

我可以做些什么来使测试更可靠和稳定?非常感谢任何提示。

2 个答案:

答案 0 :(得分:3)

按照@ P.T.的建议,我最终制作了一个自定义可重复使用的“预期条件”

waitForCssValue = function (elementFinder, cssProperty, cssValue) {
    return function () {
        return elementFinder.getCssValue(cssProperty).then(function(actualValue) {
            return actualValue === cssValue;
        });
    };
};

使用示例:

browser.wait(waitForCssValue(scope.page.forgotPassword, "color", "rgba(42, 100, 150, 1)"), 1000);
browser.wait(waitForCssValue(scope.page.forgotPassword, "text-decoration", "underline"), 1000);

答案 1 :(得分:1)

CSS更新中的这种异步似乎是量角器/ webdriver应该能够等待的东西。您的应用是否在悬停时实施CSS更新有什么不寻常之处?它是以某种方式指定动画或更新延迟吗?

那就是说,我认为有时候量角器不能知道更新可能需要一些时间,所以我认为你可以用不同的方法编写测试。而不是期望价值成为你想要的(并与浏览器中的变化竞争),你可以重新将测试称为“等待 - 直到价值 - 我想要显示”吗? (失败的情况稍微慢一些,但很有希望,但很少见。)

检查text-decoration移动到'下划线'似乎更简单(并且可能两者都会立即改变),所以你只需要等待一个,然后再检查另一个?)

删除:

expect(scope.page.forgotPassword.getCssValue("text-decoration")).toEqual("underline");

并使用类似未经测试的代码:

browser.wait(function() { 
 return scope.page.forgotPassword.getCssValue("text-decoration")).then(function(value) {
   return value === 'underline';
 });

(或者使用Expected Conditions基础设施吗?)

你应该能够隐藏一个功能中的一些丑陋:

function waitForValue(valPromise, expectedVal) {
   return browser.wait(function() {
      return valPromise.then(function(value) {
         return value === expectedValue;
      });
   });
}

// Now your test can contain:
waitForValue(scope.page.forgotPassword.getCssValue("text-decoration"), 'underline');