mirror of
https://github.com/thoughtbot/capybara-webkit
synced 2023-03-27 23:22:28 -04:00
Implement modal (confirm, prompt and alert) API
* Retain backwards compatibility with legacy capybara-webkit API. * Confirm dialogs are accepted by default; dialogs are dismissed. * Legacy API overrides the default action, and does not raise errors for unexpected modals.
This commit is contained in:
parent
144a43ff7b
commit
b411f53cfc
17 changed files with 559 additions and 31 deletions
|
@ -2,7 +2,7 @@ PATH
|
|||
remote: .
|
||||
specs:
|
||||
capybara-webkit (1.2.0)
|
||||
capybara (>= 2.0.2, < 2.4.0)
|
||||
capybara (>= 2.0.2, < 2.5.0)
|
||||
json
|
||||
|
||||
GEM
|
||||
|
@ -12,7 +12,7 @@ GEM
|
|||
appraisal (0.4.0)
|
||||
bundler
|
||||
rake
|
||||
capybara (2.3.0)
|
||||
capybara (2.4.1)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
|
|
|
@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|||
|
||||
s.required_ruby_version = ">= 1.9.0"
|
||||
|
||||
s.add_runtime_dependency("capybara", ">= 2.0.2", "< 2.4.0")
|
||||
s.add_runtime_dependency("capybara", ">= 2.0.2", "< 2.5.0")
|
||||
s.add_runtime_dependency("json")
|
||||
|
||||
s.add_development_dependency("rspec", "~> 2.14.0")
|
||||
|
|
|
@ -134,18 +134,38 @@ module Capybara::Webkit
|
|||
|
||||
alias_method :window_handle, :get_window_handle
|
||||
|
||||
def accept_confirm(options)
|
||||
command("SetConfirmAction", "Yes", options[:text])
|
||||
end
|
||||
|
||||
def accept_js_confirms
|
||||
command("SetConfirmAction", "Yes")
|
||||
end
|
||||
|
||||
def reject_confirm(options)
|
||||
command("SetConfirmAction", "No", options[:text])
|
||||
end
|
||||
|
||||
def reject_js_confirms
|
||||
command("SetConfirmAction", "No")
|
||||
end
|
||||
|
||||
def accept_prompt(options)
|
||||
if options[:with]
|
||||
command("SetPromptAction", "Yes", options[:text], options[:with])
|
||||
else
|
||||
command("SetPromptAction", "Yes", options[:text])
|
||||
end
|
||||
end
|
||||
|
||||
def accept_js_prompts
|
||||
command("SetPromptAction", "Yes")
|
||||
end
|
||||
|
||||
def reject_prompt(options)
|
||||
command("SetPromptAction", "No", options[:text])
|
||||
end
|
||||
|
||||
def reject_js_prompts
|
||||
command("SetPromptAction", "No")
|
||||
end
|
||||
|
@ -158,6 +178,14 @@ module Capybara::Webkit
|
|||
command("ClearPromptText")
|
||||
end
|
||||
|
||||
def accept_alert(options)
|
||||
command("AcceptAlert", options[:text])
|
||||
end
|
||||
|
||||
def find_modal(id)
|
||||
command("FindModal", id)
|
||||
end
|
||||
|
||||
def url_blacklist=(black_list)
|
||||
command("SetUrlBlacklist", *Array(black_list))
|
||||
end
|
||||
|
|
|
@ -175,6 +175,38 @@ module Capybara::Webkit
|
|||
browser.go_forward
|
||||
end
|
||||
|
||||
def accept_modal(type, options={})
|
||||
options = modal_action_options_for_browser(options)
|
||||
|
||||
case type
|
||||
when :confirm
|
||||
id = browser.accept_confirm(options)
|
||||
when :prompt
|
||||
id = browser.accept_prompt(options)
|
||||
else
|
||||
id = browser.accept_alert(options)
|
||||
end
|
||||
|
||||
yield
|
||||
|
||||
find_modal(type, id, options)
|
||||
end
|
||||
|
||||
def dismiss_modal(type, options={})
|
||||
options = modal_action_options_for_browser(options)
|
||||
|
||||
case type
|
||||
when :confirm
|
||||
id = browser.reject_confirm(options)
|
||||
else
|
||||
id = browser.reject_prompt(options)
|
||||
end
|
||||
|
||||
yield
|
||||
|
||||
find_modal(type, id, options)
|
||||
end
|
||||
|
||||
def wait?
|
||||
true
|
||||
end
|
||||
|
@ -217,5 +249,32 @@ module Capybara::Webkit
|
|||
browser.version
|
||||
].join("\n")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def modal_action_options_for_browser(options)
|
||||
if options[:text].is_a?(Regexp)
|
||||
options.merge(text: options[:text].source)
|
||||
else
|
||||
options.merge(text: Regexp.escape(options[:text].to_s))
|
||||
end.merge(original_text: options[:text])
|
||||
end
|
||||
|
||||
def find_modal(type, id, options)
|
||||
Timeout::timeout(options[:wait] || Capybara.default_wait_time) do
|
||||
begin
|
||||
browser.find_modal(id)
|
||||
rescue ModalIndexError
|
||||
sleep 0.05
|
||||
retry
|
||||
end
|
||||
end
|
||||
rescue ModalNotFound
|
||||
raise Capybara::ModalNotFound,
|
||||
"Unable to find modal dialog#{" with #{options[:original_text]}" if options[:original_text]}"
|
||||
rescue Timeout::Error
|
||||
raise Capybara::ModalNotFound,
|
||||
"Timed out waiting for modal dialog#{" with #{options[:original_text]}" if options[:original_text]}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,6 +20,12 @@ module Capybara::Webkit
|
|||
class ConnectionError < StandardError
|
||||
end
|
||||
|
||||
class ModalIndexError < StandardError
|
||||
end
|
||||
|
||||
class ModalNotFound < StandardError
|
||||
end
|
||||
|
||||
class JsonError
|
||||
def initialize(response)
|
||||
error = JSON.parse response
|
||||
|
|
|
@ -620,26 +620,95 @@ describe Capybara::Webkit::Driver do
|
|||
context "javascript dialog interaction" do
|
||||
context "on an alert app" do
|
||||
let(:driver) do
|
||||
driver_for_html(<<-HTML)
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
alert("Alert Text\\nGoes Here");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
driver_for_app do
|
||||
get '/' do
|
||||
<<-HTML
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
alert("Alert Text\\nGoes Here");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
end
|
||||
|
||||
get '/async' do
|
||||
<<-HTML
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
function testAlert() {
|
||||
setTimeout(function() { alert("Alert Text\\nGoes Here"); },
|
||||
#{params[:sleep] || 100});
|
||||
}
|
||||
</script>
|
||||
<input type="button" onclick="testAlert()" name="test"/>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
before { visit("/") }
|
||||
it 'accepts any alert modal if no match is provided' do
|
||||
alert_message = driver.accept_modal(:alert) do
|
||||
visit("/")
|
||||
end
|
||||
alert_message.should eq "Alert Text\nGoes Here"
|
||||
end
|
||||
|
||||
it 'accepts an alert modal if it matches' do
|
||||
alert_message = driver.accept_modal(:alert, text: "Alert Text\nGoes Here") do
|
||||
visit("/")
|
||||
end
|
||||
alert_message.should eq "Alert Text\nGoes Here"
|
||||
end
|
||||
|
||||
it 'raises an error when accepting an alert modal that does not match' do
|
||||
expect {
|
||||
driver.accept_modal(:alert, text: 'No?') do
|
||||
visit('/')
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog with No?"
|
||||
end
|
||||
|
||||
it 'waits to accept an async alert modal' do
|
||||
visit("/async")
|
||||
alert_message = driver.accept_modal(:alert) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
alert_message.should eq "Alert Text\nGoes Here"
|
||||
end
|
||||
|
||||
it 'times out waiting for an async alert modal' do
|
||||
visit("/async?sleep=1000")
|
||||
expect {
|
||||
driver.accept_modal(:alert, wait: 0.1) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Timed out waiting for modal dialog"
|
||||
end
|
||||
|
||||
it 'raises an error when an unexpected modal is displayed' do
|
||||
expect {
|
||||
driver.accept_modal(:confirm) do
|
||||
visit("/")
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog"
|
||||
end
|
||||
|
||||
it "should let me read my alert messages" do
|
||||
visit("/")
|
||||
driver.alert_messages.first.should eq "Alert Text\nGoes Here"
|
||||
end
|
||||
|
||||
it "empties the array when reset" do
|
||||
visit("/")
|
||||
driver.reset!
|
||||
driver.alert_messages.should be_empty
|
||||
end
|
||||
|
@ -659,8 +728,25 @@ describe Capybara::Webkit::Driver do
|
|||
else
|
||||
console.log("goodbye");
|
||||
}
|
||||
function test_complex_dialog() {
|
||||
if(confirm("Yes?"))
|
||||
if(confirm("Really?"))
|
||||
console.log("hello");
|
||||
else
|
||||
console.log("goodbye");
|
||||
}
|
||||
function test_async_dialog() {
|
||||
setTimeout(function() {
|
||||
if(confirm("Yes?"))
|
||||
console.log("hello");
|
||||
else
|
||||
console.log("goodbye");
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
<input type="button" onclick="test_dialog()" name="test"/>
|
||||
<input type="button" onclick="test_complex_dialog()" name="test_complex"/>
|
||||
<input type="button" onclick="test_async_dialog()" name="test_async"/>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
@ -668,6 +754,81 @@ describe Capybara::Webkit::Driver do
|
|||
|
||||
before { visit("/") }
|
||||
|
||||
it 'accepts any confirm modal if no match is provided' do
|
||||
driver.accept_modal(:confirm) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "hello"
|
||||
end
|
||||
|
||||
it 'dismisses a confirm modal that does not match' do
|
||||
begin
|
||||
driver.accept_modal(:confirm, text: 'No?') do
|
||||
driver.find_xpath("//input").first.click
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
rescue Capybara::ModalNotFound
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error when accepting a confirm modal that does not match' do
|
||||
expect {
|
||||
driver.accept_modal(:confirm, text: 'No?') do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog with No?"
|
||||
end
|
||||
|
||||
it 'dismisses any confirm modal if no match is provided' do
|
||||
driver.dismiss_modal(:confirm) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
|
||||
it 'raises an error when dismissing a confirm modal that does not match' do
|
||||
expect {
|
||||
driver.dismiss_modal(:confirm, text: 'No?') do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog with No?"
|
||||
end
|
||||
|
||||
it 'waits to accept an async confirm modal' do
|
||||
visit("/async")
|
||||
confirm_message = driver.accept_modal(:confirm) do
|
||||
driver.find_css("input[name=test_async]").first.click
|
||||
end
|
||||
confirm_message.should eq "Yes?"
|
||||
end
|
||||
|
||||
it 'allows the nesting of dismiss and accept' do
|
||||
driver.dismiss_modal(:confirm) do
|
||||
driver.accept_modal(:confirm) do
|
||||
driver.find_css("input[name=test_complex]").first.click
|
||||
end
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
|
||||
it 'raises an error when an unexpected modal is displayed' do
|
||||
expect {
|
||||
driver.accept_modal(:prompt) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog"
|
||||
end
|
||||
|
||||
it 'dismisses a confirm modal when prompt is expected' do
|
||||
begin
|
||||
driver.accept_modal(:prompt) do
|
||||
driver.find_xpath("//input").first.click
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
rescue Capybara::ModalNotFound
|
||||
end
|
||||
end
|
||||
|
||||
it "should default to accept the confirm" do
|
||||
driver.find_xpath("//input").first.click
|
||||
driver.console_messages.first[:message].should eq "hello"
|
||||
|
@ -727,8 +888,23 @@ describe Capybara::Webkit::Driver do
|
|||
else
|
||||
console.log("goodbye");
|
||||
}
|
||||
function test_complex_dialog() {
|
||||
var response = prompt("Your name?", "John Smith");
|
||||
if(response != null)
|
||||
if(prompt("Your age?"))
|
||||
console.log("hello " + response);
|
||||
else
|
||||
console.log("goodbye");
|
||||
}
|
||||
function test_async_dialog() {
|
||||
setTimeout(function() {
|
||||
var response = prompt("Your name?", "John Smith");
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
<input type="button" onclick="test_dialog()" name="test"/>
|
||||
<input type="button" onclick="test_complex_dialog()" name="test_complex"/>
|
||||
<input type="button" onclick="test_async_dialog()" name="test_async"/>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
@ -736,6 +912,88 @@ describe Capybara::Webkit::Driver do
|
|||
|
||||
before { visit("/") }
|
||||
|
||||
it 'accepts any prompt modal if no match is provided' do
|
||||
driver.accept_modal(:prompt) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "hello John Smith"
|
||||
end
|
||||
|
||||
it 'accepts any prompt modal with the provided response' do
|
||||
driver.accept_modal(:prompt, with: 'Capy') do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "hello Capy"
|
||||
end
|
||||
|
||||
it 'raises an error when accepting a prompt modal that does not match' do
|
||||
expect {
|
||||
driver.accept_modal(:prompt, text: 'Your age?') do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog with Your age?"
|
||||
end
|
||||
|
||||
it 'dismisses any prompt modal if no match is provided' do
|
||||
driver.dismiss_modal(:prompt) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
|
||||
it 'dismisses a prompt modal that does not match' do
|
||||
begin
|
||||
driver.accept_modal(:prompt, text: 'Your age?') do
|
||||
driver.find_xpath("//input").first.click
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
rescue Capybara::ModalNotFound
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error when dismissing a prompt modal that does not match' do
|
||||
expect {
|
||||
driver.dismiss_modal(:prompt, text: 'Your age?') do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog with Your age?"
|
||||
end
|
||||
|
||||
it 'waits to accept an async prompt modal' do
|
||||
visit("/async")
|
||||
prompt_message = driver.accept_modal(:prompt) do
|
||||
driver.find_css("input[name=test_async]").first.click
|
||||
end
|
||||
prompt_message.should eq "Your name?"
|
||||
end
|
||||
|
||||
it 'allows the nesting of dismiss and accept' do
|
||||
driver.dismiss_modal(:prompt) do
|
||||
driver.accept_modal(:prompt) do
|
||||
driver.find_css("input[name=test_complex]").first.click
|
||||
end
|
||||
end
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
|
||||
it 'raises an error when an unexpected modal is displayed' do
|
||||
expect {
|
||||
driver.accept_modal(:confirm) do
|
||||
driver.find_xpath("//input").first.click
|
||||
end
|
||||
}.to raise_error Capybara::ModalNotFound, "Unable to find modal dialog"
|
||||
end
|
||||
|
||||
it 'dismisses a prompt modal when confirm is expected' do
|
||||
begin
|
||||
driver.accept_modal(:confirm) do
|
||||
driver.find_xpath("//input").first.click
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
end
|
||||
rescue Capybara::ModalNotFound
|
||||
end
|
||||
end
|
||||
|
||||
it "should default to dismiss the prompt" do
|
||||
driver.find_xpath("//input").first.click
|
||||
driver.console_messages.first[:message].should eq "goodbye"
|
||||
|
|
11
src/AcceptAlert.cpp
Normal file
11
src/AcceptAlert.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "AcceptAlert.h"
|
||||
#include "SocketCommand.h"
|
||||
#include "WebPage.h"
|
||||
#include "WebPageManager.h"
|
||||
|
||||
AcceptAlert::AcceptAlert(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
||||
}
|
||||
|
||||
void AcceptAlert::start() {
|
||||
finish(true, page()->acceptAlert(arguments()[0]));
|
||||
}
|
10
src/AcceptAlert.h
Normal file
10
src/AcceptAlert.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "SocketCommand.h"
|
||||
|
||||
class AcceptAlert : public SocketCommand {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AcceptAlert(WebPageManager *, QStringList &arguments, QObject *parent = 0);
|
||||
virtual void start();
|
||||
};
|
||||
|
|
@ -46,6 +46,8 @@
|
|||
#include "WindowMaximize.h"
|
||||
#include "GoBack.h"
|
||||
#include "GoForward.h"
|
||||
#include "AcceptAlert.h"
|
||||
#include "FindModal.h"
|
||||
|
||||
CommandFactory::CommandFactory(WebPageManager *manager, QObject *parent) : QObject(parent) {
|
||||
m_manager = manager;
|
||||
|
|
21
src/FindModal.cpp
Normal file
21
src/FindModal.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "FindModal.h"
|
||||
#include "SocketCommand.h"
|
||||
#include "WebPage.h"
|
||||
#include "WebPageManager.h"
|
||||
#include "ErrorMessage.h"
|
||||
|
||||
FindModal::FindModal(WebPageManager *manager, QStringList &arguments, QObject *parent) : SocketCommand(manager, arguments, parent) {
|
||||
}
|
||||
|
||||
void FindModal::start() {
|
||||
int modalId = arguments()[0].toInt();
|
||||
if (page()->modalCount() < modalId) {
|
||||
finish(false, new ErrorMessage("ModalIndexError", ""));
|
||||
} else {
|
||||
if (page()->modalMessage(modalId).isNull()) {
|
||||
finish(false, new ErrorMessage("ModalNotFound", ""));
|
||||
} else {
|
||||
finish(true, page()->modalMessage(modalId));
|
||||
}
|
||||
}
|
||||
}
|
10
src/FindModal.h
Normal file
10
src/FindModal.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "SocketCommand.h"
|
||||
|
||||
class FindModal : public SocketCommand {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FindModal(WebPageManager *, QStringList &arguments, QObject *parent = 0);
|
||||
virtual void start();
|
||||
};
|
||||
|
|
@ -6,6 +6,14 @@ SetConfirmAction::SetConfirmAction(WebPageManager *manager, QStringList &argumen
|
|||
|
||||
void SetConfirmAction::start()
|
||||
{
|
||||
page()->setConfirmAction(arguments()[0]);
|
||||
finish(true);
|
||||
QString index;
|
||||
switch (arguments().length()) {
|
||||
case 2:
|
||||
index = page()->setConfirmAction(arguments()[0], arguments()[1]);
|
||||
break;
|
||||
default:
|
||||
page()->setConfirmAction(arguments()[0]);
|
||||
}
|
||||
|
||||
finish(true, index);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,17 @@ SetPromptAction::SetPromptAction(WebPageManager *manager, QStringList &arguments
|
|||
|
||||
void SetPromptAction::start()
|
||||
{
|
||||
page()->setPromptAction(arguments()[0]);
|
||||
finish(true);
|
||||
QString index;
|
||||
switch (arguments().length()) {
|
||||
case 3:
|
||||
index = page()->setPromptAction(arguments()[0], arguments()[1], arguments()[2]);
|
||||
break;
|
||||
case 2:
|
||||
index = page()->setPromptAction(arguments()[0], arguments()[1]);
|
||||
break;
|
||||
default:
|
||||
page()->setPromptAction(arguments()[0]);
|
||||
}
|
||||
|
||||
finish(true, index);
|
||||
}
|
||||
|
|
109
src/WebPage.cpp
109
src/WebPage.cpp
|
@ -19,14 +19,13 @@ WebPage::WebPage(WebPageManager *manager, QObject *parent) : QWebPage(parent) {
|
|||
m_failed = false;
|
||||
m_manager = manager;
|
||||
m_uuid = QUuid::createUuid().toString();
|
||||
m_confirmAction = true;
|
||||
m_promptAction = false;
|
||||
|
||||
setForwardUnsupportedContent(true);
|
||||
loadJavascript();
|
||||
setUserStylesheet();
|
||||
|
||||
m_confirm = true;
|
||||
m_prompt = false;
|
||||
m_prompt_text = QString();
|
||||
this->setCustomNetworkAccessManager();
|
||||
|
||||
connect(this, SIGNAL(loadStarted()), this, SLOT(loadStarted()));
|
||||
|
@ -180,26 +179,71 @@ void WebPage::javaScriptConsoleMessage(const QString &message, int lineNumber, c
|
|||
void WebPage::javaScriptAlert(QWebFrame *frame, const QString &message) {
|
||||
Q_UNUSED(frame);
|
||||
m_alertMessages.append(message);
|
||||
|
||||
if (m_modalResponses.isEmpty()) {
|
||||
m_modalMessages << QString();
|
||||
} else {
|
||||
QVariantMap alertResponse = m_modalResponses.takeLast();
|
||||
bool expectedType = alertResponse["type"].toString() == "alert";
|
||||
QRegExp expectedMessage = alertResponse["message"].toRegExp();
|
||||
|
||||
addModalMessage(expectedType, message, expectedMessage);
|
||||
}
|
||||
|
||||
m_manager->logger() << "ALERT:" << qPrintable(message);
|
||||
}
|
||||
|
||||
bool WebPage::javaScriptConfirm(QWebFrame *frame, const QString &message) {
|
||||
Q_UNUSED(frame);
|
||||
m_confirmMessages.append(message);
|
||||
return m_confirm;
|
||||
|
||||
if (m_modalResponses.isEmpty()) {
|
||||
m_modalMessages << QString();
|
||||
return m_confirmAction;
|
||||
} else {
|
||||
QVariantMap confirmResponse = m_modalResponses.takeLast();
|
||||
bool expectedType = confirmResponse["type"].toString() == "confirm";
|
||||
QRegExp expectedMessage = confirmResponse["message"].toRegExp();
|
||||
|
||||
addModalMessage(expectedType, message, expectedMessage);
|
||||
return expectedType &&
|
||||
confirmResponse["action"].toBool() &&
|
||||
message.contains(expectedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
bool WebPage::javaScriptPrompt(QWebFrame *frame, const QString &message, const QString &defaultValue, QString *result) {
|
||||
Q_UNUSED(frame)
|
||||
m_promptMessages.append(message);
|
||||
if (m_prompt) {
|
||||
if (m_prompt_text.isNull()) {
|
||||
|
||||
bool action = false;
|
||||
QString response;
|
||||
|
||||
if (m_modalResponses.isEmpty()) {
|
||||
action = m_promptAction;
|
||||
response = m_prompt_text;
|
||||
m_modalMessages << QString();
|
||||
} else {
|
||||
QVariantMap promptResponse = m_modalResponses.takeLast();
|
||||
bool expectedType = promptResponse["type"].toString() == "prompt";
|
||||
QRegExp expectedMessage = promptResponse["message"].toRegExp();
|
||||
|
||||
action = expectedType &&
|
||||
promptResponse["action"].toBool() &&
|
||||
message.contains(expectedMessage);
|
||||
response = promptResponse["response"].toString();
|
||||
addModalMessage(expectedType, message, expectedMessage);
|
||||
}
|
||||
|
||||
if (action) {
|
||||
if (response.isNull()) {
|
||||
*result = defaultValue;
|
||||
} else {
|
||||
*result = m_prompt_text;
|
||||
*result = response;
|
||||
}
|
||||
}
|
||||
return m_prompt;
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
void WebPage::loadStarted() {
|
||||
|
@ -376,15 +420,60 @@ void WebPage::remove() {
|
|||
m_manager->removePage(this);
|
||||
}
|
||||
|
||||
QString WebPage::setConfirmAction(QString action, QString message) {
|
||||
QVariantMap confirmResponse;
|
||||
confirmResponse["type"] = "confirm";
|
||||
confirmResponse["action"] = (action=="Yes");
|
||||
confirmResponse["message"] = QRegExp(message);
|
||||
m_modalResponses << confirmResponse;
|
||||
return QString::number(m_modalResponses.length());
|
||||
}
|
||||
|
||||
void WebPage::setConfirmAction(QString action) {
|
||||
m_confirm = (action == "Yes");
|
||||
m_confirmAction = (action == "Yes");
|
||||
}
|
||||
|
||||
QString WebPage::setPromptAction(QString action, QString message, QString response) {
|
||||
QVariantMap promptResponse;
|
||||
promptResponse["type"] = "prompt";
|
||||
promptResponse["action"] = (action == "Yes");
|
||||
promptResponse["message"] = QRegExp(message);
|
||||
promptResponse["response"] = response;
|
||||
m_modalResponses << promptResponse;
|
||||
return QString::number(m_modalResponses.length());
|
||||
}
|
||||
|
||||
QString WebPage::setPromptAction(QString action, QString message) {
|
||||
return setPromptAction(action, message, QString());
|
||||
}
|
||||
|
||||
void WebPage::setPromptAction(QString action) {
|
||||
m_prompt = (action == "Yes");
|
||||
m_promptAction = (action == "Yes");
|
||||
}
|
||||
|
||||
void WebPage::setPromptText(QString text) {
|
||||
m_prompt_text = text;
|
||||
}
|
||||
|
||||
QString WebPage::acceptAlert(QString message) {
|
||||
QVariantMap alertResponse;
|
||||
alertResponse["type"] = "alert";
|
||||
alertResponse["message"] = QRegExp(message);
|
||||
m_modalResponses << alertResponse;
|
||||
return QString::number(m_modalResponses.length());
|
||||
}
|
||||
|
||||
int WebPage::modalCount() {
|
||||
return m_modalMessages.length();
|
||||
}
|
||||
|
||||
QString WebPage::modalMessage(int id) {
|
||||
return m_modalMessages[id - 1];
|
||||
}
|
||||
|
||||
void WebPage::addModalMessage(bool expectedType, const QString &message, const QRegExp &expectedMessage) {
|
||||
if (expectedType && message.contains(expectedMessage))
|
||||
m_modalMessages << message;
|
||||
else
|
||||
m_modalMessages << QString();
|
||||
}
|
||||
|
|
|
@ -23,8 +23,12 @@ class WebPage : public QWebPage {
|
|||
QString userAgentForUrl(const QUrl &url ) const;
|
||||
void setUserAgent(QString userAgent);
|
||||
void setConfirmAction(QString action);
|
||||
QString setConfirmAction(QString action, QString message);
|
||||
QString setPromptAction(QString action, QString message, QString response);
|
||||
QString setPromptAction(QString action, QString message);
|
||||
void setPromptAction(QString action);
|
||||
void setPromptText(QString action);
|
||||
QString acceptAlert(QString);
|
||||
int getLastStatus();
|
||||
void setCustomNetworkAccessManager();
|
||||
bool render(const QString &fileName, const QSize &minimumSize);
|
||||
|
@ -48,6 +52,8 @@ class WebPage : public QWebPage {
|
|||
void mouseEvent(QEvent::Type type, const QPoint &position, Qt::MouseButton button);
|
||||
bool clickTest(QWebElement element, int absoluteX, int absoluteY);
|
||||
void resize(int, int);
|
||||
int modalCount();
|
||||
QString modalMessage(int);
|
||||
|
||||
public slots:
|
||||
bool shouldInterruptJavaScript();
|
||||
|
@ -82,8 +88,8 @@ class WebPage : public QWebPage {
|
|||
QStringList getAttachedFileNames();
|
||||
void loadJavascript();
|
||||
void setUserStylesheet();
|
||||
bool m_confirm;
|
||||
bool m_prompt;
|
||||
bool m_confirmAction;
|
||||
bool m_promptAction;
|
||||
QVariantList m_consoleMessages;
|
||||
QVariantList m_alertMessages;
|
||||
QVariantList m_confirmMessages;
|
||||
|
@ -94,6 +100,9 @@ class WebPage : public QWebPage {
|
|||
QString m_errorPageMessage;
|
||||
void setFrameProperties(QWebFrame *, QUrl &, NetworkReplyProxy *);
|
||||
QPoint m_mousePosition;
|
||||
QList<QVariantMap> m_modalResponses;
|
||||
QStringList m_modalMessages;
|
||||
void addModalMessage(bool, const QString &, const QRegExp &);
|
||||
};
|
||||
|
||||
#endif //_WEBPAGE_H
|
||||
|
|
|
@ -48,3 +48,5 @@ CHECK_COMMAND(WindowSize)
|
|||
CHECK_COMMAND(WindowMaximize)
|
||||
CHECK_COMMAND(GoBack)
|
||||
CHECK_COMMAND(GoForward)
|
||||
CHECK_COMMAND(AcceptAlert)
|
||||
CHECK_COMMAND(FindModal)
|
||||
|
|
|
@ -7,6 +7,8 @@ PRECOMPILED_DIR = $${BUILD_DIR}
|
|||
OBJECTS_DIR = $${BUILD_DIR}
|
||||
MOC_DIR = $${BUILD_DIR}
|
||||
HEADERS = \
|
||||
FindModal.h \
|
||||
AcceptAlert.h \
|
||||
GoForward.h \
|
||||
GoBack.h \
|
||||
WindowMaximize.h \
|
||||
|
@ -79,6 +81,8 @@ HEADERS = \
|
|||
StdinNotifier.h
|
||||
|
||||
SOURCES = \
|
||||
FindModal.cpp \
|
||||
AcceptAlert.cpp \
|
||||
GoForward.cpp \
|
||||
GoBack.cpp \
|
||||
WindowMaximize.cpp \
|
||||
|
|
Loading…
Add table
Reference in a new issue