最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - RGBRGBA color values in Protractor - Stack Overflow

programmeradmin0浏览0评论

The Story:

In several places in our test codebase we assert different CSS values to be equal to expected values. Usually, this is a color, background-color, font related style properties, or cursor. This question is about dealing with colors.

Here is an example working test that currently passes:

describe("AngularJS home page", function () {
    beforeEach(function () {
        browser.get("/");
    });

    it("should show a blue Download button", function () {
        var downloadButton = element(by.partialLinkText("Download"));

        expect(downloadButton.getCssValue("background-color")).toEqual("rgba(0, 116, 204, 1)");
    });
});

It checks that the Download button on the AngularJS website has 0, 116, 204, 1 RGBA value.

Now, if the color would change, the test would fail as, for example:

Expected 'rgba(0, 116, 204, 1)' to equal 'rgba(255, 116, 204, 1)'.

The Problems:

  • As you can see, first of all, the expectation itself is not quite readable. Unless we put a ment near it, it is not obvious what color are we expecting to see.

  • Also, the error message is not informative. It is unclear what an actual color is and what color are we expecting to see.

The Question:

Is it possible to improve the test itself and the error message to be more readable and informative and operate color names instead of color RGB/RGBA values?

Desired expectation:

expect(downloadButton).toHaveBackgroundColor("midnight blue");

Desired error messages:

Expect 'blue' to equal 'black'
Expect 'dark grey' to equal 'light sea green'

Currently, I'm thinking about making a custom jasmine matcher that would convert the RGB/RGBA value to a custom Color object that would keep the original value as well as determine the closest color. color npm package looks very promising.

Would appreciate any hints.

The Story:

In several places in our test codebase we assert different CSS values to be equal to expected values. Usually, this is a color, background-color, font related style properties, or cursor. This question is about dealing with colors.

Here is an example working test that currently passes:

describe("AngularJS home page", function () {
    beforeEach(function () {
        browser.get("https://angularjs/");
    });

    it("should show a blue Download button", function () {
        var downloadButton = element(by.partialLinkText("Download"));

        expect(downloadButton.getCssValue("background-color")).toEqual("rgba(0, 116, 204, 1)");
    });
});

It checks that the Download button on the AngularJS website has 0, 116, 204, 1 RGBA value.

Now, if the color would change, the test would fail as, for example:

Expected 'rgba(0, 116, 204, 1)' to equal 'rgba(255, 116, 204, 1)'.

The Problems:

  • As you can see, first of all, the expectation itself is not quite readable. Unless we put a ment near it, it is not obvious what color are we expecting to see.

  • Also, the error message is not informative. It is unclear what an actual color is and what color are we expecting to see.

The Question:

Is it possible to improve the test itself and the error message to be more readable and informative and operate color names instead of color RGB/RGBA values?

Desired expectation:

expect(downloadButton).toHaveBackgroundColor("midnight blue");

Desired error messages:

Expect 'blue' to equal 'black'
Expect 'dark grey' to equal 'light sea green'

Currently, I'm thinking about making a custom jasmine matcher that would convert the RGB/RGBA value to a custom Color object that would keep the original value as well as determine the closest color. color npm package looks very promising.

Would appreciate any hints.

Share Improve this question edited Dec 29, 2015 at 1:20 alecxe asked Dec 27, 2015 at 6:01 alecxealecxe 474k127 gold badges1.1k silver badges1.2k bronze badges 8
  • Are all the puted values guaranteed to correspond to named colors? – BoltClock Commented Dec 27, 2015 at 6:10
  • @BoltClock good question. I would stick to some base mapping between rgb->color name, and if a color name not found, we can just show the actual original rgb(a) value..I understand, it is probably not going to be bullet-proof, but I hope practical. – alecxe Commented Dec 27, 2015 at 6:11
  • 4 Most of the websites have their own set of colors, usually there is not a lot of them, but it depends on a design. I would think of creating a simple JS object as a map for colors and color names, specific to your website, and not rely on another lib: { 'red': 'rgba(255, 0, 0, 1)', 'blue': 'rgba(0, 0, 255, 1)' } and match against them. – Michael Radionov Commented Dec 27, 2015 at 9:47
  • I would opt for color roles, not colors per se.. although that's not 1:1. – user2864740 Commented Dec 31, 2015 at 3:45
  • 2 @alecxe The tests I've written target classes, but even in the case of Michael's suggestion it could be { 'warning': 'rgb(255, 0, 0, 1)' }. That's still lower than I'd prefer to deal with though and human 'visual' testing catches the layout/rendering flaws - that can manifest in so many ridiculous ways across different devices - much better than Selenium can. – user2864740 Commented Dec 31, 2015 at 4:46
 |  Show 3 more ments

2 Answers 2

Reset to default 8 +50

Protractor uses Jasmine as its testing framework by default and it provides a mechanism for adding custom expectations.

So, you could do something like this:

In your protractor config file:

var customMatchers = {
  toHaveBackgroundColor: function(util, customEqualityTesters) {
      pare: function(actual, expected) {
        result.pass = util.equals(extractColor(actual), convertToRGB(expected), customEqualityTesters);
        result.message = 'Expected ' + actual + ' to be color ' + expected';
      }
   }
}

jasmine.addMatchers(customMatchers);

function convertToRGB(color) {
  // convert a named color to rgb
}

function extractColor(domElement) {
  // extract background color from dom element
}

And to use it:

expect(downloadButton).toHaveBackgroundColor("midnight blue");

I haven't tried this out, but this is the basic idea of what you need.

I got a working answer based on @Andrew and @Manasov remendations.

So the custom expectation would be like this:

var nameColor = require('name-that-color/lib/ntc');
var rgbHex = require('rgb-hex');

toHaveColor: function() {
    return {
        pare: function (elem, color) {
            var result = {};
            result.pass = elem.getCssValue("color").then(function(cssColor) {
                var hexColor = rgbHex(cssColor);
                var colorName = nameColor.name('#' + hexColor.substring(0, 6).toUpperCase());
                result.message = "Expect '" + colorName[1] + "' to equal '" + color + "'";
                return colorName[1] === color;
            });
            return result;
        }
    }
}

We need to first install the necessary packages:

npm install name-that-color
npm install rgb-hex

We first need to convert the rgb color into hex. Also we have to remove the alpha from the color for name-that-color to actually match it against a color name, it can be removed from the hex conversion.

Now we can just simple call it like:

expect(downloadButton).toHaveColor("midnight blue");
发布评论

评论列表(0)

  1. 暂无评论