diff --git a/lib/capybara/driver/webkit.rb b/lib/capybara/driver/webkit.rb index 5c990e8..06e9399 100644 --- a/lib/capybara/driver/webkit.rb +++ b/lib/capybara/driver/webkit.rb @@ -27,7 +27,7 @@ class Capybara::Driver::Webkit end def current_url - browser.url + browser.current_url end def requested_url diff --git a/lib/capybara/driver/webkit/browser.rb b/lib/capybara/driver/webkit/browser.rb index f26d3ae..b4f76c3 100644 --- a/lib/capybara/driver/webkit/browser.rb +++ b/lib/capybara/driver/webkit/browser.rb @@ -70,6 +70,10 @@ class Capybara::Driver::Webkit command("RequestedUrl") end + def current_url + command("CurrentUrl") + end + def frame_focus(frame_id_or_index=nil) if frame_id_or_index.is_a? Fixnum command("FrameFocus", "", frame_id_or_index.to_s) diff --git a/src/CommandFactory.cpp b/src/CommandFactory.cpp index c81c2c0..c35a01e 100644 --- a/src/CommandFactory.cpp +++ b/src/CommandFactory.cpp @@ -20,6 +20,7 @@ #include "SetProxy.h" #include "ConsoleMessages.h" #include "RequestedUrl.h" +#include "CurrentUrl.h" CommandFactory::CommandFactory(WebPage *page, QObject *parent) : QObject(parent) { m_page = page; diff --git a/src/CurrentUrl.cpp b/src/CurrentUrl.cpp new file mode 100644 index 0000000..1664f0d --- /dev/null +++ b/src/CurrentUrl.cpp @@ -0,0 +1,71 @@ +#include "CurrentUrl.h" +#include "WebPage.h" + +CurrentUrl::CurrentUrl(WebPage *page, QObject *parent) : Command(page, parent) { +} + +/* + * This CurrentUrl command attempts to produce a current_url value consistent + * with that returned by the Selenium WebDriver Capybara driver. + * + * It does not currently return the correct value in the case of an iframe whose + * source URL results in a redirect because the loading of the iframe does not + * generate a history item. This is most likely a rare case and is consistent + * with the current behavior of the capybara-webkit driver. + * + * The following two values are *not* affected by Javascript pushState. + * + * QWebFrame->url() + * QWebHistoryItem.originalUrl() + * + * The following two values *are* affected by Javascript pushState. + * + * QWebFrame->requestedUrl() + * QWebHistoryItem.url() + * + * In the cases that we have access to both the QWebFrame values and the + * correct history item for that frame, we can compare the values and determine + * if a redirect occurred and if pushState was used. The table below describes + * the various combinations of URL values that are possible. + * + * O -> originally requested URL + * R -> URL after redirection + * P -> URL set by pushState + * * -> denotes the desired URL value from the frame + * + * frame history + * case url requestedUrl url originalUrl + * ----------------------------------------------------------------- + * regular load O O* O O + * + * redirect w/o R* O R O + * pushState + * + * pushState O P* P O + * only + * + * redirect w/ R P* P O + * pushState + * + * Based on the above information, we only need to check for the case of a + * redirect w/o pushState, in which case QWebFrame->url() will have the correct + * current_url value. In all other cases QWebFrame->requestedUrl() is correct. + */ +void CurrentUrl::start(QStringList &arguments) { + Q_UNUSED(arguments); + + QUrl humanUrl = wasRedirectedAndNotModifiedByJavascript() ? + page()->currentFrame()->url() : page()->currentFrame()->requestedUrl(); + QByteArray encodedBytes = humanUrl.toEncoded(); + QString urlString = QString(encodedBytes); + emit finished(new Response(true, urlString)); +} + +bool CurrentUrl::wasRegularLoad() { + return page()->currentFrame()->url() == page()->currentFrame()->requestedUrl(); +} + +bool CurrentUrl::wasRedirectedAndNotModifiedByJavascript() { + return !wasRegularLoad() && page()->currentFrame()->url() == page()->history()->currentItem().url(); +} + diff --git a/src/CurrentUrl.h b/src/CurrentUrl.h new file mode 100644 index 0000000..1db07bd --- /dev/null +++ b/src/CurrentUrl.h @@ -0,0 +1,16 @@ +#include "Command.h" + +class WebPage; + +class CurrentUrl : public Command { + Q_OBJECT + + public: + CurrentUrl(WebPage *page, QObject *parent = 0); + virtual void start(QStringList &arguments); + + private: + bool wasRegularLoad(); + bool wasRedirectedAndNotModifiedByJavascript(); +}; + diff --git a/src/find_command.h b/src/find_command.h index 152c2fa..4298941 100644 --- a/src/find_command.h +++ b/src/find_command.h @@ -24,3 +24,4 @@ CHECK_COMMAND(Headers) CHECK_COMMAND(SetProxy) CHECK_COMMAND(ConsoleMessages) CHECK_COMMAND(RequestedUrl) +CHECK_COMMAND(CurrentUrl) diff --git a/src/webkit_server.pro b/src/webkit_server.pro index 3e31143..8f0c8e4 100644 --- a/src/webkit_server.pro +++ b/src/webkit_server.pro @@ -2,6 +2,7 @@ TEMPLATE = app TARGET = webkit_server DESTDIR = . HEADERS = \ + CurrentUrl.h \ RequestedUrl.h \ ConsoleMessages.h \ WebPage.h \ @@ -35,6 +36,7 @@ HEADERS = \ SetProxy.h \ SOURCES = \ + CurrentUrl.cpp \ RequestedUrl.cpp \ ConsoleMessages.cpp \ main.cpp \