mirror of
https://github.com/thoughtbot/capybara-webkit
synced 2023-03-27 23:22:28 -04:00
Adding ability to render webpage to a PNG
The driver has a #render method which takes a destination file path and an options hash for setting the dimensions of the browser's viewport
This commit is contained in:
parent
8cfb09ee4c
commit
17873240b1
13 changed files with 168 additions and 4 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -12,3 +12,6 @@ moc_*.cpp
|
|||
.bundle
|
||||
pkg
|
||||
src/webkit_server
|
||||
.DS_Store
|
||||
tmp
|
||||
.rvmrc
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -2,4 +2,4 @@ source "http://rubygems.org"
|
|||
gem "rspec", :require => false
|
||||
gem "capybara"
|
||||
gem "sinatra", :require => false
|
||||
|
||||
gem "mini_magick", :require => false
|
||||
|
|
|
@ -19,6 +19,8 @@ GEM
|
|||
rake (>= 0.8.7)
|
||||
json_pure (1.5.1)
|
||||
mime-types (1.16)
|
||||
mini_magick (3.2.1)
|
||||
subexec (~> 0.0.4)
|
||||
nokogiri (1.4.4)
|
||||
rack (1.2.1)
|
||||
rack-test (0.5.7)
|
||||
|
@ -41,6 +43,7 @@ GEM
|
|||
sinatra (1.1.2)
|
||||
rack (~> 1.1)
|
||||
tilt (~> 1.2)
|
||||
subexec (0.0.4)
|
||||
tilt (1.2.2)
|
||||
xpath (0.1.3)
|
||||
nokogiri (~> 1.3)
|
||||
|
@ -50,5 +53,6 @@ PLATFORMS
|
|||
|
||||
DEPENDENCIES
|
||||
capybara
|
||||
mini_magick
|
||||
rspec
|
||||
sinatra
|
||||
|
|
|
@ -84,6 +84,14 @@ class Capybara::Driver::Webkit
|
|||
false
|
||||
end
|
||||
|
||||
def render(path, options={})
|
||||
options[:width] ||= 1000
|
||||
options[:height] ||= 10
|
||||
|
||||
browser.render path, options[:width], options[:height]
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def url(path)
|
||||
|
|
|
@ -64,6 +64,10 @@ class Capybara::Driver::Webkit
|
|||
command('Execute', script)
|
||||
end
|
||||
|
||||
def render(path, width, height)
|
||||
command "Render", path, width, height
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def start_server
|
||||
|
|
79
spec/driver_rendering_spec.rb
Normal file
79
spec/driver_rendering_spec.rb
Normal file
|
@ -0,0 +1,79 @@
|
|||
require 'spec_helper'
|
||||
require 'capybara/driver/webkit'
|
||||
require 'mini_magick'
|
||||
|
||||
describe Capybara::Driver::Webkit, "rendering an image" do
|
||||
|
||||
before(:all) do
|
||||
# Set up the tmp directory and file name
|
||||
tmp_dir = File.join(PROJECT_ROOT, 'tmp')
|
||||
FileUtils.mkdir_p tmp_dir
|
||||
@file_name = File.join(tmp_dir, 'render-test.png')
|
||||
|
||||
app = lambda do |env|
|
||||
body = <<-HTML
|
||||
<html>
|
||||
<body>
|
||||
<h1>Hello World</h1>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
[200,
|
||||
{ 'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s },
|
||||
[body]]
|
||||
end
|
||||
|
||||
@driver = Capybara::Driver::Webkit.new(app, :browser => $webkit_browser)
|
||||
@driver.visit("/hello/world?success=true")
|
||||
end
|
||||
|
||||
after(:all) { @driver.reset! }
|
||||
|
||||
def render(options)
|
||||
FileUtils.rm_f @file_name
|
||||
@driver.render @file_name, options
|
||||
|
||||
@image = MiniMagick::Image.open @file_name
|
||||
end
|
||||
|
||||
context "with default options" do
|
||||
before(:all){ render({}) }
|
||||
|
||||
it "should be a PNG" do
|
||||
@image[:format].should == "PNG"
|
||||
end
|
||||
|
||||
it "width default to 1000px (with 15px less for the scrollbar)" do
|
||||
@image[:width].should == 1000-15
|
||||
end
|
||||
|
||||
it "height should be at least 10px" do
|
||||
@image[:height].should >= 10
|
||||
end
|
||||
end
|
||||
|
||||
context "with dimensions set larger than necessary" do
|
||||
before(:all){ render(:width => 500, :height => 400) }
|
||||
|
||||
it "width should match the width given" do
|
||||
@image[:width].should == 500
|
||||
end
|
||||
|
||||
it "height should match the height given" do
|
||||
@image[:height].should > 10
|
||||
end
|
||||
end
|
||||
|
||||
context "with dimensions set smaller than the document's default" do
|
||||
before(:all){ render(:width => 50, :height => 10) }
|
||||
|
||||
it "width should be greater than the width given" do
|
||||
@image[:width].should > 50
|
||||
end
|
||||
|
||||
it "height should be greater than the height given" do
|
||||
@image[:height].should > 10
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -11,6 +11,7 @@
|
|||
#include "Execute.h"
|
||||
#include "FrameFocus.h"
|
||||
#include "Header.h"
|
||||
#include "Render.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <iostream>
|
||||
|
|
19
src/Render.cpp
Normal file
19
src/Render.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "Render.h"
|
||||
#include "WebPage.h"
|
||||
|
||||
Render::Render(WebPage *page, QObject *parent) : Command(page, parent) {
|
||||
}
|
||||
|
||||
void Render::start(QStringList &arguments) {
|
||||
QStringList functionArguments(arguments);
|
||||
QString imagePath = functionArguments.takeFirst();
|
||||
int width = functionArguments.takeFirst().toInt();
|
||||
int height = functionArguments.takeFirst().toInt();
|
||||
|
||||
QSize size(width, height);
|
||||
page()->setViewportSize(size);
|
||||
|
||||
bool result = page()->render( imagePath );
|
||||
|
||||
emit finished(new Response(result));
|
||||
}
|
12
src/Render.h
Normal file
12
src/Render.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "Command.h"
|
||||
#include <QStringList>
|
||||
|
||||
class WebPage;
|
||||
|
||||
class Render : public Command {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Render(WebPage *page, QObject *parent = 0);
|
||||
virtual void start(QStringList &arguments);
|
||||
};
|
|
@ -106,3 +106,35 @@ QString WebPage::failureString() {
|
|||
return QString("Unable to load URL: ") + currentFrame()->requestedUrl().toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Swiped from Phantom.js, but removed code for rendering to PDFs and GIFs
|
||||
*
|
||||
* Takes a QString of the file path to save the image to
|
||||
* Returns true if it was able to save the file
|
||||
*/
|
||||
bool WebPage::render(const QString &fileName) {
|
||||
QFileInfo fileInfo(fileName);
|
||||
QDir dir;
|
||||
dir.mkpath(fileInfo.absolutePath());
|
||||
|
||||
QSize viewportSize = this->viewportSize();
|
||||
QSize pageSize = this->mainFrame()->contentsSize();
|
||||
if (pageSize.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QImage buffer(pageSize, QImage::Format_ARGB32);
|
||||
buffer.fill(qRgba(255, 255, 255, 0));
|
||||
|
||||
QPainter p(&buffer);
|
||||
p.setRenderHint( QPainter::Antialiasing, true);
|
||||
p.setRenderHint( QPainter::TextAntialiasing, true);
|
||||
p.setRenderHint( QPainter::SmoothPixmapTransform, true);
|
||||
|
||||
this->setViewportSize(pageSize);
|
||||
this->mainFrame()->render(&p);
|
||||
p.end();
|
||||
this->setViewportSize(viewportSize);
|
||||
|
||||
return buffer.save(fileName);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ class WebPage : public QWebPage {
|
|||
QString failureString();
|
||||
QString userAgentForUrl(const QUrl &url ) const;
|
||||
void setUserAgent(QString userAgent);
|
||||
bool render(const QString &fileName);
|
||||
|
||||
public slots:
|
||||
bool shouldInterruptJavaScript();
|
||||
|
|
|
@ -13,3 +13,4 @@ CHECK_COMMAND(Evaluate)
|
|||
CHECK_COMMAND(Execute)
|
||||
CHECK_COMMAND(FrameFocus)
|
||||
CHECK_COMMAND(Header)
|
||||
CHECK_COMMAND(Render)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
TEMPLATE = app
|
||||
TARGET = webkit_server
|
||||
DESTDIR = .
|
||||
HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h Response.h NetworkAccessManager.h Header.h
|
||||
SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp Response.cpp NetworkAccessManager.cpp Header.cpp
|
||||
HEADERS = WebPage.h Server.h Connection.h Command.h Visit.h Find.h Reset.h Node.h JavascriptInvocation.h Url.h Source.h Evaluate.h Execute.h FrameFocus.h Response.h NetworkAccessManager.h Header.h Render.h
|
||||
SOURCES = main.cpp WebPage.cpp Server.cpp Connection.cpp Command.cpp Visit.cpp Find.cpp Reset.cpp Node.cpp JavascriptInvocation.cpp Url.cpp Source.cpp Evaluate.cpp Execute.cpp FrameFocus.cpp Response.cpp NetworkAccessManager.cpp Header.cpp Render.cpp
|
||||
RESOURCES = webkit_server.qrc
|
||||
QT += network webkit
|
||||
CONFIG += console
|
||||
|
|
Loading…
Reference in a new issue