如何在断言 Selenium getCssValue("background") 返回的背景颜色 rgb(255,255,255) 时将 #ffffff 转换为 #fff 或 #f

Posted

技术标签:

【中文标题】如何在断言 Selenium getCssValue("background") 返回的背景颜色 rgb(255,255,255) 时将 #ffffff 转换为 #fff 或 #fff 转换为 #ffffff【英文标题】:How to convert #ffffff to #fff or #fff to #ffffff while asserting the background color rgb(255,255,255) returned by Selenium getCssValue("background") 【发布时间】:2019-07-13 00:19:18 【问题描述】:

如何将#ffffff 转换为#fff#fff 转换为#ffffff 进行断言?

我正在使用 Selenium 中的 getCssValue("background"),它返回 rgb(255, 255, 255),我可以将其拆分为:

r -> 255 g -> 255 b -> 255

以下代码行:

String hex = String.format("#%02x%02x%02x", r, g, b);

rgb 转换为 hex 并给出如下输出:

#ffffff

但是从控制台中,背景被提取为#fff

那么理想的方式是:

#ffffff 转换为#fff#fff 转换为#ffffff

我已经通过以下几个相关讨论:

Why use #fff color on body? 提到这个问题有点主观。 CSS: Which is faster for the browser? color:#fff; or color:#ffffff; 提到 CSS 压缩器将智能优化到 #fff 版本。

但是我的测试失败了,需要转换。有什么建议吗?

【问题讨论】:

据我所知,短十六进制颜色的组合如下:#aabbcc -> #abc。您可以将日志十六进制拆分为 3 段 [aa, bb, cc] 并检查两个字符是否相同,对于短十六进制,拆分为 [a, b, c] 并复制它们。 这个问题与 Selenium 无关......这就是我删除标签的原因。一个都没提过。 @JeffC 也许你没有注意到整个讨论是基于getCssValue("background") 的输出,这非常具体到 Selenium 为什么会有所有的转化? Assert.assertEquals("rgb(255,255,255)", e.getCssValue("background")); 有什么问题?无论如何,您都要对预期值进行硬编码。 问题是How to convert #ffffff to #fff or #fff to #ffffff for Assertion?...如何获得价值与问题无关。 【参考方案1】:

您可以将replaceAll 与正则表达式一起使用,以查找所有三个部分都使用相同数字的情况:

static String getHex(int r, int g, int b) 
    return String.format("#%02x%02x%02x", r, g, b).replaceAll("^#([a-fA-F])\\1([a-fA-F])\\2([a-fA-F])\\3$", "#$1$2$3");

这会查找以# 开头的字符串,后跟三对匹配的十六进制数字,并将它们替换为短格式。 (我想我可以在你的 specific 示例中使用[a-f] 而不是[a-fA-F],因为你知道你只会得到小写,但是......)

完整示例(Ideone):

public class Example 
    public static void main(String[] args) 
        System.out.println(getHex(255, 255, 255)); // #fff
        System.out.println(getHex(255, 240, 255)); // #fff0ff
    

    static String getHex(int r, int g, int b) 
        return String.format("#%02x%02x%02x", r, g, b).replaceAll("^#([a-fA-F])\\1([a-fA-F])\\2([a-fA-F])\\3$", "#$1$2$3");
    

【讨论】:

这是一个由规范解决方案支持的想法的瑰宝。 @DebanjanB - :-) 谢谢。如果您这样做很多,可能值得使用Pattern 以避免每次都重新编译正则表达式。【参考方案2】:

您可以编写一个简单的方法,将您的 html 颜色代码“标准化”为短格式或长格式如果它们具有所有相同的十六进制数字:

public static void main(String[] args) 
    System.out.println(normalizeHtmlColors("#ffffff", true));
    System.out.println(normalizeHtmlColors("#fff", true));
    System.out.println(normalizeHtmlColors("#ffffff", false));
    System.out.println(normalizeHtmlColors("#fff", false));


public static String normalizeHtmlColors(String colorCode, boolean toShort) 
    if (toShort && colorCode.matches("^#?([0-9a-fA-F])\\15$"))
        colorCode = colorCode.replaceFirst("#?([0-9a-fA-F])\\15", "#$1$1$1");
    else if (!toShort && colorCode.matches("^#?([0-9a-fA-F])\\12$"))
        colorCode = colorCode.replaceFirst("#?([0-9a-fA-F])\\12", "#$1$1$1$1$1$1");
    return colorCode;

这将打印:

#fff
#fff
#ffffff
#ffffff

...所以你可以决定向哪个方向转变。如果输入的两种情况都不匹配,就直接返回。

【讨论】:

以上是关于如何在断言 Selenium getCssValue("background") 返回的背景颜色 rgb(255,255,255) 时将 #ffffff 转换为 #fff 或 #f的主要内容,如果未能解决你的问题,请参考以下文章

如何断言在selenium测试用例的登录成功

Selenium-IDE:如何验证/断言页面刷新

如何阻止 codeception/selenium 在断言失败时关闭浏览器窗口?

如何使用 JUnit 断言元素包含 Selenium 中的文本

Selenium WebDriver 获取边框颜色

selenium 断言和验证的区别