【问题标题】:Using Selenium to determine the visibility of elements for Print media使用 Selenium 确定印刷媒体元素的可见性
【发布时间】:2014-07-22 02:31:48
【问题描述】:

我想确定页面上的特定元素在受 CSS @media 规则控制时是否可见。

有没有办法用 Selenium 做到这一点?

我知道有 isDisplayed 方法,它考虑了 CSS,但我找不到任何东西告诉 Selenium 应用哪种媒体类型。

有没有办法做到这一点?

或者是否有另一种方法来测试网页以确保打印您想要的元素(以及您不想要的元素)?

更新:

为了清楚起见,没有计划提供 javascript 打印按钮。用户将使用浏览器(Chrome、FF 和 IE)的正常打印功能进行打印。 @media css 规则将用于控制显示和隐藏的内容。 我希望 Selenium 将它伪装成打印机而不是屏幕,这样我就可以测试某些元素是否会在页面的打印版本中可见。

【问题讨论】:

  • 我环顾四周,但不幸的是,没有人在做你想要完成的事情。我什至查看了流行的 Web Developer 扩展的源代码,但它仅适用于在 <link type="stylesheet" rel="print" 标记上指定媒体类型而不是在 CSS 中指定媒体类型时。

标签: css selenium-webdriver


【解决方案1】:

我已经设法编写了一个脚本,它可以满足您的需求:它隐藏仅屏幕样式并将仅打印样式设置为仅屏幕样式。

您需要使用 Selenium 注入以下 JavaScript:

(function pretendToBeAPrinter() {
    //For looking up if something is in the media list
    function hasMedia(list, media) {
        if (!list) return false;

        var i = list.length;
        while (i--) {
            if (list[i] === media) {
                return true;
            }
        }
        return false;
    }

    //Loop though all stylesheets
    for (var styleSheetNo = 0; styleSheetNo < document.styleSheets.length; styleSheetNo++) {
        //Current stylesheet
        var styleSheet = document.styleSheets[styleSheetNo];

        //Output debug information
        console.info("Stylesheet #" + styleSheetNo + ":");
        console.log(styleSheet);

        //First, check if any media queries have been defined on the <style> / <link> tag

        //Disable screen-only sheets
        if (hasMedia(styleSheet.media, "screen") && !hasMedia(styleSheet.media, "print")) {
            styleSheet.disabled = true;
        }

        //Display "print" stylesheets
        if (!hasMedia(styleSheet.media, "screen") && hasMedia(styleSheet.media, "print")) {
            //Add "screen" media to show on screen
            styleSheet.media.appendMedium("screen");
        }

        // Get the CSS rules in a cross-browser compatible way
        var rules;
        try {
            rules = styleSheet.cssRules;
        } catch (error) {
            console.log(error);
        }

        try {
          rules = styleSheet.rules;
        } catch (error) {
          console.log(error);
        }

        // Handle cases where styleSheet.rules is null
        if (!rules) {
            continue;
        }

        //Second, loop through all the rules in a stylesheet
        for (var ruleNo = 0; ruleNo < rules.length; ruleNo++) {
            //Current rule
            var rule = rules[ruleNo];

            //Hide screen-only rules
            if (hasMedia(rule.media, "screen") && !hasMedia(rule.media, "print")) {
                //Rule.disabled doesn't work here, so we remove the "screen" rule and add the "print" rule so it isn't shown
                console.info('Rule.media:');
                console.log(rule.media)
                rule.media.appendMedium(':not(screen)');
                rule.media.deleteMedium('screen');
                console.info('Rule.media after tampering:');
                console.log(rule.media)
            }

            //Display "print" rules
            if (!hasMedia(rule.media, "screen") && hasMedia(rule.media, "print")) {
                //Add "screen" media to show on screen
                rule.media.appendMedium("screen");
            }
        }
    }
})()

你可以see it in action at JSFiddle

书签

你也可以install it as a bookmarklet

更多信息:

注意:我只在 Google Chrome 和 Mozilla Firefox 中测试过。它在其他浏览器中可能有效,也可能无效。

【讨论】:

  • 聪明。非常聪明。我喜欢它。谢谢!
  • @TomHoward 我已经更新了脚本,所以它也可以在 Mozilla Firefox 中运行(也可能在其他浏览器中)。
  • 我在 Chrome v64 中遇到了带有 DomException 的问题,因此我更新了访问 cssRules 来处理它。有更多 JS 知识的人可能知道更好的解决方法
  • 这太棒了。正是我想要的!
【解决方案2】:

在某些情况下,使用 applitools 等可视化自动化工具会很有用。 我们在一些测试中实现了它,到目前为止效果很好。

【讨论】:

  • 我可以在它的文档中找到任何对印刷媒体的引用。可以吗?
  • 不是专门用来打印的,但它可以帮助我们分析视觉成分。
【解决方案3】:
      //jquery

     function printDetail() {
         window.print();
     }
     //html
      <button type="button" class="btn" value="Print Div" onclick="printDetail()"><i class="icon-print"></i> &nbsp;Print</button>

      //css
      @media print{
          .header{display:none;}
          .footer{display:none;}
          .leftside{display:none;}
          .rightside{display:block;}

     }

  // http://jsfiddle.net/kisspa/52H7g/

【讨论】:

  • 是的,那么如何使用 selenium(或其他工具)检查打印时是否不显示标题?
  • 是的,我的朋友,whitin @media print 使用 display:none 和 display:block;所以
    使用 css media print{header{display:none;}} 而另一个使用 display:none 和 display:block;
  • 嗯,不,这就是你实现它的方式。这个问题是关于如何测试的。即如果有人将其更改为 @media print{header{display:none;}} 我希望 CI 服务器上的测试失败,因此有人可以去修复它。
  • 我不认为你理解我的问题。我已经知道如何使用@media 规则。我没有的是一个自动化测试,可以确认页面上的某些内容在打印时是否可见。例如,假设我团队中的开发人员更改了页面或 CSS,因此特定表格不再可见。在这些情况下,我希望测试失败。更重要的是,我们使用的是 TDD,我什至不知道从哪里开始这个测试。
【解决方案4】:

我想我有一个聪明的方法可以做到这一点:

  1. 我可以假设 PRINT 按钮将出现在 html 页面上,就像上面 jsfiddle.net 链接中的情况一样?

  2. 基本上,我可以排除 FILE->PRINT 或 RIGHT CLICK->PRINT 选项吗,并且只假设有人可以打印您的页面的唯一方法是单击嵌入在您的 html 页面中的打印按钮,如图所示如果不是上面的 jsfiddle 链接,其他测试用例是什么?

  3. 最后,我可以假设您的 selenium 测试只能在 Chrome 浏览器中运行,而不能在 firefox 中运行吗?这很重要,因为 PRINT 命令在 Chrome 中的行为与在 Firefox 中的行为不同。我的修复只适用于 Chrome。

【讨论】:

  • 没有打印按钮的计划。用户将使用浏览器(Chrome、FF 和 IE)的正常打印功能进行打印。 @media css 规则将用于控制显示和隐藏的内容。我想让 Selenium 假装它是一台打印机而不是屏幕,这样我就可以测试某些元素是否会在页面上的打印版本中可见。
猜你喜欢
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 1970-01-01
相关资源
最近更新 更多