Skip to content
This repository has been archived by the owner on Nov 27, 2020. It is now read-only.

Integration of onResourceRequested (Issue #403) #438

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

* Added ability to set zoom_factor (Dmytro Budnyk)
* Write JSON to the logger, rather than Ruby [Issue #430]
* Added ability to block http requests (Alexander Adam)

#### Bug fixes ####

Expand Down
12 changes: 12 additions & 0 deletions lib/capybara/poltergeist/browser.rb
Expand Up @@ -204,6 +204,14 @@ def clear_network_traffic
command('clear_network_traffic')
end

def blocked_urls
command 'blocked_urls'
end

def clear_blocked_urls
command 'clear_blocked_urls'
end

def equals(page_id, id, other_id)
command('equals', page_id, id, other_id)
end
Expand Down Expand Up @@ -287,6 +295,10 @@ def command(name, *args)
raise
end

def eval_on_resource_requested(script)
command 'eval_on_resource_requested', script.strip
end

def go_back
command 'go_back'
end
Expand Down
18 changes: 17 additions & 1 deletion lib/capybara/poltergeist/client/browser.coffee
Expand Up @@ -165,8 +165,17 @@ class Poltergeist.Browser
@page.execute("function() { #{script} }")
this.sendResponse(true)

eval_on_resource_requested: (script) ->
@page.evalOnResourceRequested = eval("(#{script})")
this.sendResponse(true)

frame_url: (frame_name) ->
@page.frameUrl(frame_name)

push_frame: (name, timeout = new Date().getTime() + 2000) ->
if @page.pushFrame(name)
if @frame_url(name) in @page.blockedUrls()
this.sendResponse(true)
else if @page.pushFrame(name)
if @page.currentUrl() == 'about:blank'
this.setState 'awaiting_frame_load'
else
Expand Down Expand Up @@ -308,6 +317,13 @@ class Poltergeist.Browser
@page.clearNetworkTraffic()
this.sendResponse(true)

blocked_urls: ->
this.sendResponse(@page.blockedUrls())

clear_blocked_urls: ->
@page.clearBlockedUrls()
this.sendResponse(true)

get_headers: ->
this.sendResponse(@page.getCustomHeaders())

Expand Down
27 changes: 25 additions & 2 deletions lib/capybara/poltergeist/client/compiled/browser.js
@@ -1,3 +1,5 @@
var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

Poltergeist.Browser = (function() {
function Browser(owner, width, height) {
this.owner = owner;
Expand Down Expand Up @@ -204,12 +206,24 @@ Poltergeist.Browser = (function() {
return this.sendResponse(true);
};

Browser.prototype.eval_on_resource_requested = function(script) {
this.page.evalOnResourceRequested = eval("(" + script + ")");
return this.sendResponse(true);
};

Browser.prototype.frame_url = function(frame_name) {
return this.page.frameUrl(frame_name);
};

Browser.prototype.push_frame = function(name, timeout) {
var _this = this;
var _ref,
_this = this;
if (timeout == null) {
timeout = new Date().getTime() + 2000;
}
if (this.page.pushFrame(name)) {
if (_ref = this.frame_url(name), __indexOf.call(this.page.blockedUrls(), _ref) >= 0) {
return this.sendResponse(true);
} else if (this.page.pushFrame(name)) {
if (this.page.currentUrl() === 'about:blank') {
return this.setState('awaiting_frame_load');
} else {
Expand Down Expand Up @@ -413,6 +427,15 @@ Poltergeist.Browser = (function() {
return this.sendResponse(true);
};

Browser.prototype.blocked_urls = function() {
return this.sendResponse(this.page.blockedUrls());
};

Browser.prototype.clear_blocked_urls = function() {
this.page.clearBlockedUrls();
return this.sendResponse(true);
};

Browser.prototype.get_headers = function() {
return this.sendResponse(this.page.getCustomHeaders());
};
Expand Down
41 changes: 34 additions & 7 deletions lib/capybara/poltergeist/client/compiled/web_page.js
@@ -1,4 +1,5 @@
var __slice = [].slice;
var __slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

Poltergeist.WebPage = (function() {
var command, delegate, _fn, _fn1, _i, _j, _len, _len1, _ref, _ref1,
Expand Down Expand Up @@ -118,14 +119,23 @@ Poltergeist.WebPage = (function() {
});
};

WebPage.prototype.onResourceRequestedNative = function(request) {
this.lastRequestId = request.id;
if (request.url === this.redirectURL) {
WebPage.prototype.onResourceRequestedNative = function(requestData, networkRequest) {
var _ref2;
if (this.hasOwnProperty('evalOnResourceRequested') && !this.evalOnResourceRequested(requestData)) {
this._blockedUrls || (this._blockedUrls = []);
if (_ref2 = requestData.url, __indexOf.call(this._blockedUrls, _ref2) < 0) {
this._blockedUrls.push(requestData.url);
}
networkRequest.abort();
return;
}
this.lastRequestId = requestData.id;
if (requestData.url === this.redirectURL) {
this.redirectURL = null;
this.requestId = request.id;
this.requestId = requestData.id;
}
return this._networkTraffic[request.id] = {
request: request,
return this._networkTraffic[requestData.id] = {
request: requestData,
responseParts: []
};
};
Expand Down Expand Up @@ -158,6 +168,14 @@ Poltergeist.WebPage = (function() {
return this._networkTraffic = {};
};

WebPage.prototype.blockedUrls = function() {
return this._blockedUrls || [];
};

WebPage.prototype.clearBlockedUrls = function() {
return this._blockedUrls = [];
};

WebPage.prototype.content = function() {
return this["native"].frameContent;
};
Expand All @@ -170,6 +188,15 @@ Poltergeist.WebPage = (function() {
return this["native"].frameTitle;
};

WebPage.prototype.frameUrl = function(frameName) {
var query;
query = function(frameName) {
var _ref2;
return (_ref2 = document.querySelector("iframe[name='" + frameName + "']")) != null ? _ref2.src : void 0;
};
return this.evaluate(query, frameName);
};

WebPage.prototype.errors = function() {
return this._errors;
};
Expand Down
30 changes: 24 additions & 6 deletions lib/capybara/poltergeist/client/web_page.coffee
Expand Up @@ -71,15 +71,22 @@ class Poltergeist.WebPage

@_errors.push(message: message, stack: stackString)

onResourceRequestedNative: (request) ->
@lastRequestId = request.id
onResourceRequestedNative: (requestData, networkRequest) ->
if this.hasOwnProperty('evalOnResourceRequested') && !this.evalOnResourceRequested(requestData)
@_blockedUrls ||= []
@_blockedUrls.push requestData.url unless requestData.url in @_blockedUrls
networkRequest.abort()
return

if request.url == @redirectURL

@lastRequestId = requestData.id

if requestData.url == @redirectURL
@redirectURL = null
@requestId = request.id
@requestId = requestData.id

@_networkTraffic[request.id] = {
request: request,
@_networkTraffic[requestData.id] = {
request: requestData,
responseParts: []
}

Expand All @@ -103,6 +110,12 @@ class Poltergeist.WebPage
clearNetworkTraffic: ->
@_networkTraffic = {}

blockedUrls: ->
@_blockedUrls || []

clearBlockedUrls: ->
@_blockedUrls = []

content: ->
@native.frameContent

Expand All @@ -112,6 +125,11 @@ class Poltergeist.WebPage
title: ->
@native.frameTitle

frameUrl: (frameName) ->
query = (frameName) ->
document.querySelector("iframe[name='#{frameName}']")?.src
this.evaluate(query, frameName)

errors: ->
@_errors

Expand Down
4 changes: 4 additions & 0 deletions lib/capybara/poltergeist/driver.rb
Expand Up @@ -130,6 +130,10 @@ def evaluate_script(script)
browser.evaluate(script)
end

def eval_on_resource_requested(script)
browser.eval_on_resource_requested(script)
end

def execute_script(script)
browser.execute(script)
nil
Expand Down
18 changes: 18 additions & 0 deletions spec/integration/driver_spec.rb
Expand Up @@ -705,6 +705,24 @@ def create_screenshot(file, *args)
end
end

context 'controlling onResourceRequested' do
it 'blocks unwanted urls' do
@driver.eval_on_resource_requested <<-JS
function (request) {
return !request.url.match(/unwanted/);
}
JS
@session.visit('/poltergeist/resource_requested_test')
expect(@session.status_code).to eq(200)

expect(@driver.browser.blocked_urls.first).to end_with('unwanted')
expect(@session).to have_content('We are loading some unwanted action here')
@session.within_frame 'framename' do
expect(@session.html).not_to include('We shouldn\'t see this.')
end
end
end

context 'has ability to send keys' do
before { @session.visit('/poltergeist/send_keys') }

Expand Down
9 changes: 9 additions & 0 deletions spec/support/views/resource_requested_test.erb
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<body>
We are loading some unwanted action here.
<iframe src="/poltergeist/unwanted" name="framename"></iframe>
<img src="/poltergeist/unwanted" style="height:100px;width:100px;" />
<script src="/poltergeist/unwanted" />
</body>
</html>
6 changes: 6 additions & 0 deletions spec/support/views/unwanted.erb
@@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
We shouldn't see this.
</body>
</html>