Implement window_handles and window_handle for proper window switching

This commit is contained in:
Matthew Horan 2012-03-27 18:49:57 -04:00
parent 468bec886f
commit fe46eaf50d
17 changed files with 130 additions and 37 deletions

View File

@ -93,14 +93,23 @@ class Capybara::Driver::Webkit
end
def within_window(handle)
current_window = window_handle
browser.window_focus(handle)
begin
yield
ensure
browser.window_focus
browser.window_focus(current_window)
end
end
def window_handles
browser.get_window_handles
end
def window_handle
browser.get_window_handle
end
def wait?
true
end

View File

@ -81,14 +81,22 @@ class Capybara::Driver::Webkit
command("SetSkipImageLoading", skip_image_loading)
end
def window_focus(handle=nil)
if handle
command("WindowFocus", handle)
else
command("WindowFocus")
end
def window_focus(handle)
command("WindowFocus", handle)
end
def get_window_handles
JSON.parse(command('GetWindowHandles'))
end
alias_method :window_handles, :get_window_handles
def get_window_handle
command('GetWindowHandle')
end
alias_method :window_handle, :get_window_handle
def command(name, *args)
@connection.puts name
@connection.puts args.size

View File

@ -1576,21 +1576,21 @@ describe Capybara::Driver::Webkit do
it "has the expected text in the new window" do
subject.visit("/new_window")
subject.within_window(true) do
subject.within_window(subject.window_handles.last) do
subject.find("//p").first.text.should == "finished"
end
end
it "waits for the new window to load" do
subject.visit("/new_window?sleep=1")
subject.within_window(true) do
subject.within_window(subject.window_handles.last) do
lambda { Timeout::timeout(1) { subject.find("//p") } }.should_not raise_error(Timeout::Error)
end
end
it "switches back to the original window" do
subject.visit("/new_window")
subject.within_window(true) { }
subject.within_window(subject.window_handles.last) { }
subject.find("//p").first.text.should == "bananas"
end
end

View File

@ -16,6 +16,7 @@ class Command : public QObject {
signals:
void finished(Response *response);
void windowChanged(WebPage *);
protected:
WebPage *page();

View File

@ -26,6 +26,8 @@
#include "IgnoreSslErrors.h"
#include "SetSkipImageLoading.h"
#include "WindowFocus.h"
#include "GetWindowHandles.h"
#include "GetWindowHandle.h"
CommandFactory::CommandFactory(WebPage *page, QObject *parent) : QObject(parent) {
m_page = page;

9
src/GetWindowHandle.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "GetWindowHandle.h"
#include <QStringList>
GetWindowHandle::GetWindowHandle(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void GetWindowHandle::start() {
emit finished(new Response(true, page()->uuid()));
}

11
src/GetWindowHandle.h Normal file
View File

@ -0,0 +1,11 @@
#include "Command.h"
#include "WebPage.h"
class GetWindowHandle : public Command {
Q_OBJECT
public:
GetWindowHandle(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

22
src/GetWindowHandles.cpp Normal file
View File

@ -0,0 +1,22 @@
#include "GetWindowHandles.h"
#include "WebPageManager.h"
#include <QStringList>
GetWindowHandles::GetWindowHandles(WebPage *page, QStringList &arguments, QObject *parent) : Command(page, arguments, parent) {
}
void GetWindowHandles::start() {
QListIterator<WebPage *> pageIterator =
WebPageManager::getInstance()->iterator();
QString handles = "[";
QStringList stringList;
while (pageIterator.hasNext()) {
stringList.append("\"" + pageIterator.next()->uuid() + "\"");
}
handles += stringList.join(",") + "]";
emit finished(new Response(true, handles));
}

12
src/GetWindowHandles.h Normal file
View File

@ -0,0 +1,12 @@
#include "Command.h"
class WebPage;
class GetWindowHandles : public Command {
Q_OBJECT
public:
GetWindowHandles(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
};

View File

@ -7,6 +7,7 @@
#include <QResource>
#include <iostream>
#include <QWebSettings>
#include <QUuid>
WebPage::WebPage(QObject *parent) : QWebPage(parent) {
setForwardUnsupportedContent(true);
@ -27,6 +28,8 @@ WebPage::WebPage(QObject *parent) : QWebPage(parent) {
settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
WebPageManager::getInstance()->append(this);
m_uuid = QUuid::createUuid().toString();
}
void WebPage::resetWindowSize() {
@ -251,3 +254,7 @@ QWebPage *WebPage::createWindow(WebWindowType type) {
Q_UNUSED(type);
return new WebPage(this);
}
QString WebPage::uuid() {
return m_uuid;
}

View File

@ -23,6 +23,7 @@ class WebPage : public QWebPage {
void resetConsoleMessages();
void resetWindowSize();
QWebPage *createWindow(WebWindowType type);
QString uuid();
public slots:
bool shouldInterruptJavaScript();
@ -57,6 +58,7 @@ class WebPage : public QWebPage {
QString m_pageHeaders;
bool m_ignoreSslErrors;
QStringList m_consoleMessages;
QString m_uuid;
};
#endif //_WEBPAGE_H

View File

@ -3,7 +3,6 @@
WebPageManager *WebPageManager::m_instance = NULL;
WebPageManager::WebPageManager() {
webPages = new QList<WebPage*>();
}
WebPageManager *WebPageManager::getInstance() {
@ -14,14 +13,10 @@ WebPageManager *WebPageManager::getInstance() {
}
void WebPageManager::append(WebPage *value) {
webPages->append(value);
m_pages.append(value);
}
WebPage *WebPageManager::first() {
return (WebPage*) webPages->first();
}
WebPage *WebPageManager::last() {
return (WebPage*) webPages->last();
QListIterator<WebPage *> WebPageManager::iterator() {
return QListIterator<WebPage *>(m_pages);
}

View File

@ -1,3 +1,5 @@
#ifndef _WEBPAGEMANAGER_H
#define _WEBPAGEMANAGER_H
#include "WebPage.h"
#include <QList>
@ -5,12 +7,13 @@ class WebPageManager {
public:
static WebPageManager *getInstance();
void append(WebPage *value);
WebPage *first();
WebPage *last();
QListIterator<WebPage *> iterator();
private:
WebPageManager();
QList<WebPage*> *webPages;
QList<WebPage *> m_pages;
static WebPageManager *m_instance;
};
#endif // _WEBPAGEMANAGER_H

View File

@ -7,23 +7,30 @@ WindowFocus::WindowFocus(WebPage *page, QStringList &arguments, QObject *parent)
}
void WindowFocus::start() {
WebPageManager *manager = WebPageManager::getInstance();
switch(arguments().length()) {
case 1:
emit windowChanged(manager->last());
success();
break;
default:
emit windowChanged(manager->first());
success();
}
focusWindow(arguments()[0]);
}
void WindowFocus::windowNotFound() {
emit finished(new Response(false, QString("Unable to locate window. ")));
}
void WindowFocus::success() {
void WindowFocus::success(WebPage *page) {
emit windowChanged(page);
emit finished(new Response(true));
}
void WindowFocus::focusWindow(QString selector) {
QListIterator<WebPage *> pageIterator =
WebPageManager::getInstance()->iterator();
while (pageIterator.hasNext()) {
WebPage *page = pageIterator.next();
if (selector == page->uuid()) {
success(page);
return;
}
}
windowNotFound();
}

View File

@ -1,4 +1,5 @@
#include "Command.h"
#include "WebPageManager.h"
class WebPage;
@ -9,11 +10,9 @@ class WindowFocus : public Command {
WindowFocus(WebPage *page, QStringList &arguments, QObject *parent = 0);
virtual void start();
signals:
void windowChanged(WebPage *);
private:
void success();
void success(WebPage *);
void windowNotFound();
void focusWindow(QString);
};

View File

@ -29,3 +29,5 @@ CHECK_COMMAND(ResizeWindow)
CHECK_COMMAND(IgnoreSslErrors)
CHECK_COMMAND(SetSkipImageLoading)
CHECK_COMMAND(WindowFocus)
CHECK_COMMAND(GetWindowHandles)
CHECK_COMMAND(GetWindowHandle)

View File

@ -41,6 +41,8 @@ HEADERS = \
SetSkipImageLoading.h \
WebPageManager.h \
WindowFocus.h \
GetWindowHandles.h \
GetWindowHandle.h \
SOURCES = \
IgnoreSslErrors.cpp \
@ -83,6 +85,8 @@ SOURCES = \
SetSkipImageLoading.cpp \
WebPageManager.cpp \
WindowFocus.cpp \
GetWindowHandles.cpp \
GetWindowHandle.cpp \
RESOURCES = webkit_server.qrc
QT += network webkit