From 76a362c66462634ad8d21eb964f5bb8dd7319205 Mon Sep 17 00:00:00 2001 From: Joe Ferris and Matt Horan Date: Sat, 9 Nov 2013 14:34:43 -0500 Subject: [PATCH] Save a screenshot when raising a ClickFailed exception * Prints the path to the file * Make it easier to debug what was actually clicked --- spec/integration/session_spec.rb | 13 ++++++++----- src/JavascriptInvocation.cpp | 11 +++++++++++ src/JavascriptInvocation.h | 1 + src/capybara.js | 1 + 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/spec/integration/session_spec.rb b/spec/integration/session_spec.rb index ee9e13d..106edfe 100644 --- a/spec/integration/session_spec.rb +++ b/spec/integration/session_spec.rb @@ -415,12 +415,15 @@ describe Capybara::Session do two.style.top = '0px'; JS - lambda { + expect { subject.find(:css, '#one').click - }.should raise_error( - Capybara::Webkit::ClickFailed, - /Failed.*\[@id='one'\].*overlapping.*\[@id='two'\].*at position/ - ) + }.to raise_error(Capybara::Webkit::ClickFailed) { |exception| + exception.message.should =~ %r{Failed.*\[@id='one'\].*overlapping.*\[@id='two'\].*at position} + screenshot_pattern = %r{A screenshot of the page at the time of the failure has been written to (.*)} + exception.message.should =~ screenshot_pattern + file = exception.message.match(screenshot_pattern)[1] + File.exist?(file).should be_true + } end it 'raises an error if a checkbox is obscured when checked' do diff --git a/src/JavascriptInvocation.cpp b/src/JavascriptInvocation.cpp index e79c35f..432365c 100644 --- a/src/JavascriptInvocation.cpp +++ b/src/JavascriptInvocation.cpp @@ -139,3 +139,14 @@ void JavascriptInvocation::keypress(QChar key) { event = QKeyEvent(QKeyEvent::KeyRelease, keyCode, Qt::NoModifier, key); QApplication::sendEvent(m_page, &event); } + +const QString JavascriptInvocation::render(void) { + QString pathTemplate = + QDir::temp().absoluteFilePath("./click_failed_XXXXXX.png"); + QTemporaryFile file(pathTemplate); + file.open(); + file.setAutoRemove(false); + QString path = file.fileName(); + m_page->render(path, QSize(1024, 768)); + return path; +} diff --git a/src/JavascriptInvocation.h b/src/JavascriptInvocation.h index 966ae01..970c1b9 100644 --- a/src/JavascriptInvocation.h +++ b/src/JavascriptInvocation.h @@ -24,6 +24,7 @@ class JavascriptInvocation : public QObject { Q_INVOKABLE QVariantMap clickPosition(QWebElement element, int left, int top, int width, int height); Q_INVOKABLE void hover(int absoluteX, int absoluteY); Q_INVOKABLE void keypress(QChar); + Q_INVOKABLE const QString render(void); QVariant getError(); void setError(QVariant error); InvocationResult invoke(QWebFrame *); diff --git a/src/capybara.js b/src/capybara.js index 8d31c5f..1a9b71c 100644 --- a/src/capybara.js +++ b/src/capybara.js @@ -376,6 +376,7 @@ Capybara.ClickFailed = function(expectedPath, actualPath, position) { this.message += ' at position ' + position["absoluteX"] + ', ' + position["absoluteY"]; else this.message += ' at unknown position'; + this.message += "; \nA screenshot of the page at the time of the failure has been written to " + CapybaraInvocation.render(); }; Capybara.ClickFailed.prototype = new Error(); Capybara.ClickFailed.prototype.constructor = Capybara.ClickFailed;