Ruby 如何使用Watir和geckodriver+;火狐?

Ruby 如何使用Watir和geckodriver+;火狐?,ruby,firefox,selenium-webdriver,watir,geckodriver,Ruby,Firefox,Selenium Webdriver,Watir,Geckodriver,我将我的Watir/Firefox自动化堆栈升级到最新版本,并添加了geckodriver。我很惊讶地看到,现在屏幕截图只是默认情况下的视口截图 require 'watir' require 'mini_magick' b = Watir::Browser.new :firefox b.goto "https://daringfireball.net" base = b.screenshot.base64 blob = Base64.decode64(base) image = MiniMa

我将我的Watir/Firefox自动化堆栈升级到最新版本,并添加了geckodriver。我很惊讶地看到,现在屏幕截图只是默认情况下的视口截图

require 'watir'
require 'mini_magick'

b = Watir::Browser.new :firefox
b.goto "https://daringfireball.net"
base = b.screenshot.base64
blob = Base64.decode64(base)
image = MiniMagick::Image.read(blob)
image.height
 => 1760 # macOS 'Retina' resolution doubling
b.execute_script "return window.innerHeight"
 => 880 # 880 * 2 = 1760
b.execute_script "return document.documentElement.scrollHeight"
 => 34692


如何使用Watir驱动Firefox拍摄整个页面的屏幕截图而不回滚我的环境?

使用Watir的
。执行脚本
,可以在移动滚动位置的同时重复拍摄视口的屏幕截图。然后可以使用MiniMagick将图像缝合在一起

我开发了封装我解决这个问题的最佳方法,尽管它附带了警告,您可以在那里阅读。它也是内存密集型的,速度可能很慢

这不是一个真正的全页屏幕截图解决方案,我很乐意接受任何在这方面有所改进的替代方法。

我用C#解决了这个问题。但是我想这个解决方案可以在任何语言上重写。我使用了一个名为HTML2Canvas的JavaScript库来生成整个页面的屏幕截图。以下是C#代码:


您可以在中找到更多的示例和解释。

现在可以在Firefox中使用geckodriver功能实现这一点。据我所知,这个特性并没有加入到Selenium中/可能不是W3C规范的一部分

需要“watir”
browser=Watir::browser.new:firefox
bridge=browser.driver.session\u storage.instance\u variable\u get(:@bridge)
server\u uri=bridge.instance\u variable\u get(:@http)。instance\u variable\u get(:@server\u url)
sid=bridge.instance\u variable\u get(:@session\u id)
driver_path=“session/#{sid}/moz/screenshot/full”
请求\u url=服务器\u uri.to\u s+驱动程序\u路径
url=URI.parse(请求\ url)
req=Net::HTTP::Get.new(请求url)
raw=Net::HTTP.start(url.host,url.port){| HTTP | HTTP.request(req)}.body
base64_屏幕截图=JSON.parse(原始,符号化_名称:true)[:value]
这种方法现在也是以下领域的一种选择:

需要“watir屏幕截图缝合”
b=Watir::Browser.new:firefox
b、 后藤“https://github.com/mozilla/geckodriver/issues/570"
base64_屏幕截图=b.base64_壁虎河

感谢您分享此方法。我可以将它添加到我的Ruby gem中。这个解决方案使用了什么版本的HTML2Canvas?使用这种方法我只会收到解析错误(如果我手动修复解析问题,则会出现超时)。版本是6个月前的版本。它和它配合得很好。
[Test]
public void TakingHTML2CanvasFullPageScreenshot()
{
    using (var driver = new ChromeDriver())
    {
        driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);
        driver.Navigate().GoToUrl(@"https://automatetheplanet.com");
        IJavaScriptExecutor js = driver;
        var html2canvasJs = File.ReadAllText($"{GetAssemblyDirectory()}html2canvas.js");
        js.ExecuteScript(html2canvasJs);
        string generateScreenshotJS = @"function genScreenshot () {
                                            var canvasImgContentDecoded;
                                            html2canvas(document.body, {
                                                onrendered: function (canvas) {                                          
                                                    window.canvasImgContentDecoded = canvas.toDataURL(""image/png"");
                                            }});
                                        }
                                        genScreenshot();";
        js.ExecuteScript(generateScreenshotJS);
        var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
        wait.IgnoreExceptionTypes(typeof(InvalidOperationException));
        wait.Until(
            wd =>
            {
                string response = (string)js.ExecuteScript
                    ("return (typeof canvasImgContentDecoded === 'undefined' || canvasImgContentDecoded === null)");
                if (string.IsNullOrEmpty(response))
                {
                    return false;
                }
                return bool.Parse(response);
            });
        wait.Until(wd => !string.IsNullOrEmpty((string)js.ExecuteScript("return canvasImgContentDecoded;")));
        var pngContent = (string)js.ExecuteScript("return canvasImgContentDecoded;");
        pngContent = pngContent.Replace("data:image/png;base64,", string.Empty);
        byte[] data = Convert.FromBase64String(pngContent);
        var tempFilePath = Path.GetTempFileName().Replace(".tmp", ".png");
        Image image;
        using (var ms = new MemoryStream(data))
        {
            image = Image.FromStream(ms);
        }
        image.Save(tempFilePath, ImageFormat.Png);
    }
}