如何截取移动外形的全高?

How can I screenshot the full height of a mobile form factor?

测试移动设备外形尺寸时,Chrome 仅截取可见部分 window。我同意这是标准和预期的行为。但是,我还想捕获页面的完整滚动高度,以便我可以检查整个页面的呈现。

我认为最简单的解决方案是将 chrome window 高度设置为足够大的值,这样就完成了。但是,Chrome window 高度似乎受限于我的物理屏幕高度,即。我使用 browser.manage().window().setSize(375,5000); 将其设置为 5,000,但它只会调整到 1,200 的高度。

我已经知道[根据 WebDriver 规范][1],[takeScreenshot() 函数][2] 不应该捕获整个页面,但应该只对可见区域进行截图。

OP 编辑​​:我选择了最后一个选项,我在下面标记了“工作解决方案!!

下面是解决问题的不同类型分组策略。


滚动、截图、追加

Quoting截图系统作者在CrossBrowserTesting.com:

As the author of the screenshot system for CrossBrowserTesting.com, I can tell you that the only way we've been able to get full page screenshots consistently and reliably across browsers is to scroll, capture, and append images.

以下是使用 cnn.com 作为示例目标滚动和截取可见区域屏幕截图的示例工作实现。使用 scrollHeight, clientHeight and scrollTop 来确定我们在垂直滚动位置的位置以及向下滚动的距离。由于我们在循环中处理 promise,因此我们必须创建一个具有“我们处于底部”基本条件的递归函数:

var fs = require('fs'),
    Utils = {
        screenShotDirectory: '',

        writeScreenShot: function (data, filename) {
            var stream = fs.createWriteStream(this.screenShotDirectory + filename);

            stream.write(new Buffer(data, 'base64'));
            stream.end();
        },

        getSizes: function () {
            return browser.executeScript("return {scrollHeight: document.body.scrollHeight, clientHeight: document.body.clientHeight, scrollTop: document.body.scrollTop};");
        },

        scrollToBottom: function (height, index) {
            var self = this;

            self.getSizes().then(function (data) {
                // continue only if we are not at the bottom of the page
                if (data.scrollTop + data.clientHeight < data.scrollHeight) {
                    browser.executeScript("window.scrollTo(0, arguments[0]);", height).then(function () {
                        browser.takeScreenshot().then(function (png) {
                            self.writeScreenShot(png, "test" + index + ".png");
                        });
                    });
                    self.scrollToBottom(height + data.clientHeight, index + 1);
                }
            });
        }
    };

describe("Scrolling and saving screenshots", function () {
    beforeEach(function () {
        browser.ignoreSynchronization = true;
        browser.get("http://www.cnn.com/");
    });

    it("should capture an entire page", function () {
        Utils.getSizes().then(function (data) {
            Utils.scrollToBottom(data.clientHeight * 2, 1);
        });
    });
});

它会生成多个 test<index>.png 图像,然后您可以将它们粘合在一起。

要在“单列图像”中连接图像,例如,您可以使用 GraphicsMagick Image Processing System through the gm nodejs module. The .montage() method with the concatenate option in the 1x mode 会有所帮助。示例代码:

var gm = require('gm');

Utils.getSizes().then(function (data) {
    var index = Utils.scrollToBottom(data.clientHeight * 2, 1);

    var op = gm();
    for (var i = 1; i <= index; i++) {
        op = op.in("test" + i + ".png");
    }

    op = op.montage().mode("concatenate").tile("1x");
    
    op.write('output.png', function (err) {
        if (err) console.log(err);
    });
});

更改浏览器

在 Chrome 中,您总是只能在生成的屏幕截图上看到可见区域,这里是相关的 chromedriver 问题,其中包含有关该问题的大量信息和多个解决方法:

有点令人惊讶,it should though work in Firefox - 如果可能切换到它:

Chrome screenshots that take up the entire screen are not like Firefox's. Firefox will capture the entire screen, even parts of it that are not currently viewable. Chrome will not!


调整屏幕尺寸

另一种选择是使用 BrowserStack or SauceLabs 等服务在特定平台上的特定浏览器中开始测试,并使用 特定的足够大的分辨率 。量角器支持 Sauce LabsBrowserStack out-of-the-box.

BrowserStack 的示例配置:

exports.config: {
  browserstackUser: "user",
  browserstackKey: "key",

  capabilities: {
    'browserstack.local': true,
    'browserstack.debug': true,
 
    browserName: "Chrome",
    os: "Windows",
    os_version: "8",
    resolution: "2048x1536"
  },
}

然后,最大化浏览器window(例如onPrepare()内):

browser.driver.manage().window().maximize();

并截图。


可行的解决方案!!!

另一种选择是 运行 在虚拟显示器中进行测试。我会跟随 this blogpost 并使用 Xvfb,当您 运行 Xvfb 服务器时,您可以指定分辨率:

/usr/bin/Xvfb :99 -ac -screen 0 2048x6000x24 &

另请参阅此处有关此主题的相关信息:


您也可以使用 docker-selenium solution which allows to configure the screen size