Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RGB/RGBA color values in Protractor

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.org/");
    });

    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 comment 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.

like image 952
alecxe Avatar asked Dec 27 '15 06:12

alecxe


People also ask

What are the RGBA color values?

RGBA color values are an extension of RGB color values with an alpha channel - which specifies the opacity for a color. An RGBA color value is specified with: rgba(red, green, blue, alpha). The alpha parameter is a number between 0.0 (fully transparent) and 1.0 (fully opaque).

What does rgba 255 0 0 0.2 color code in CSS means?

RGB Value. Each parameter (red, green, and blue) defines the intensity of the color between 0 and 255. For example, rgb(255, 0, 0) is displayed as red, because red is set to its highest value (255) and the others are set to 0. To display black, set all color parameters to 0, like this: rgb(0, 0, 0).

Is rgba same as RGB?

RGB is a three-channel format containing data for Red, Green, and Blue. RGBA is a four-channel format containing data for Red, Green, Blue, and an Alpha value. The CSS function rgb() has wide browser support. The CSS function rgba() may have limited support in the older browser.


2 Answers

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) {
      compare: 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.

like image 145
Andrew Eisenberg Avatar answered Oct 02 '22 12:10

Andrew Eisenberg


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

So the custom expectation would be like this:

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

toHaveColor: function() {
    return {
        compare: 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");
like image 24
eLRuLL Avatar answered Oct 02 '22 14:10

eLRuLL