1
0
Fork 0
mirror of https://github.com/thoughtbot/capybara-webkit synced 2023-03-27 23:22:28 -04:00

Fix native alerts from Ajax requests

If an Ajax request finished after a `reset` triggered an alert, a native
alert pops up. Additionally, the next request to the driver after the
native alert will crash the webkit process.
This commit is contained in:
Joe Ferris 2015-04-23 10:15:37 -04:00
parent e49176beac
commit f8f2048500
3 changed files with 50 additions and 1 deletions

View file

@ -7,7 +7,7 @@ require 'base64'
describe Capybara::Webkit::Driver do describe Capybara::Webkit::Driver do
include AppRunner include AppRunner
def visit(url, driver=driver) def visit(url, driver=self.driver)
driver.visit("#{AppRunner.app_host}#{url}") driver.visit("#{AppRunner.app_host}#{url}")
end end
@ -675,6 +675,31 @@ describe Capybara::Webkit::Driver do
HTML HTML
end end
get '/ajax' do
<<-HTML
<html>
<head>
</head>
<body>
<script type="text/javascript">
function testAlert() {
var xhr = new XMLHttpRequest();
xhr.open('GET', '/slow', true);
xhr.setRequestHeader('Content-Type', 'text/plain');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert('From ajax');
}
};
xhr.send();
}
</script>
<input type="button" onclick="testAlert()" name="test"/>
</body>
</html>
HTML
end
get '/double' do get '/double' do
<<-HTML <<-HTML
<html> <html>
@ -689,6 +714,11 @@ describe Capybara::Webkit::Driver do
</html> </html>
HTML HTML
end end
get '/slow' do
sleep 0.5
""
end
end end
end end
@ -761,6 +791,15 @@ describe Capybara::Webkit::Driver do
driver.reset! driver.reset!
driver.alert_messages.should be_empty driver.alert_messages.should be_empty
end end
it "clears alerts from ajax requests in between sessions" do
visit("/ajax")
driver.find("//input").first.click
driver.reset!
sleep 0.5
driver.alert_messages.should eq([])
expect { visit("/") }.not_to raise_error
end
end end
context "on a confirm app" do context "on a confirm app" do

View file

@ -90,6 +90,7 @@ void WebPageManager::requestCreated(QByteArray &url, QNetworkReply *reply) {
if (reply->isFinished()) if (reply->isFinished())
replyFinished(reply); replyFinished(reply);
else { else {
m_pendingReplies.append(reply);
connect(reply, SIGNAL(finished()), SLOT(handleReplyFinished())); connect(reply, SIGNAL(finished()), SLOT(handleReplyFinished()));
} }
} }
@ -103,6 +104,7 @@ void WebPageManager::handleReplyFinished() {
void WebPageManager::replyFinished(QNetworkReply *reply) { void WebPageManager::replyFinished(QNetworkReply *reply) {
int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
logger() << "Received" << status << "from" << reply->url().toString(); logger() << "Received" << status << "from" << reply->url().toString();
m_pendingReplies.removeAll(reply);
} }
void WebPageManager::setPageStatus(bool success) { void WebPageManager::setPageStatus(bool success) {
@ -144,6 +146,13 @@ void WebPageManager::reset() {
m_currentPage->resetLocalStorage(); m_currentPage->resetLocalStorage();
m_blacklistedRequestHandler->reset(); m_blacklistedRequestHandler->reset();
m_unknownUrlHandler->reset(); m_unknownUrlHandler->reset();
foreach(QNetworkReply *reply, m_pendingReplies) {
logger() << "Aborting request to" << reply->url().toString();
reply->abort();
}
m_pendingReplies.clear();
while (!m_pages.isEmpty()) { while (!m_pages.isEmpty()) {
WebPage *page = m_pages.takeFirst(); WebPage *page = m_pages.takeFirst();
page->deleteLater(); page->deleteLater();

View file

@ -58,6 +58,7 @@ class WebPageManager : public QObject {
static void handleDebugMessage(QtMsgType type, const char *message); static void handleDebugMessage(QtMsgType type, const char *message);
QList<WebPage *> m_pages; QList<WebPage *> m_pages;
QList<QNetworkReply *> m_pendingReplies;
WebPage *m_currentPage; WebPage *m_currentPage;
bool m_ignoreSslErrors; bool m_ignoreSslErrors;
NetworkCookieJar *m_cookieJar; NetworkCookieJar *m_cookieJar;