How to use python with phantomjs and selenium fake referer? - phantomjs

This is my code:
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = (
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:25.0) Gecko/20100101 Firefox/25.0 "
)
driver = webdriver.PhantomJS(desired_capabilities=dcap)
driver.get("http://pujiankang.cn/index0.html")
jscode = '''
var webPage = require('webpage');
var page = webPage.create();
var settings = {
headers: {
"Referer": "http://www.google.com"
}
};
page.onLoadStarted = function() {
page.customHeaders = {};
};
page.open('http://pujiankang.cn/index0.html', settings, function(status) {
});
'''
driver.execute_script(jscode)
driver.save_screenshot('test.png')
driver.quit
when run it then get error:
Image
errorMessage":"Can't find variable: require","request"...
But I run this js file with phantomjs directly,It's work!
command:phantomjs referer.js
How to resolve this problem?

Related

Running Chrome ignoring Cross-Origin Chrome policy

I'm trying to run Chrome using selenium webdriver without any security restrictions as part of an experiment.
Basically, I'm trying to access iframe context from different origin then my page.
Obviously, by default I'm getting the Cross-Origin exception - that's what I want to avoid and I know that I can achieve that using a browser extension, but I want to find alternatives.
Exception that I get when trying to access iframe context:
DOMException: Blocked a frame with origin "file://" from accessing a cross-origin frame.
I've tried to set any of suggested flags that I found online and official documentation when running Chrome/Chromium:
'--allow-file-access-from-files',
'--system-developer-mode',
'-–allow-file-access-from-files',
'--disable-features=IsolateOrigins',
'--disable-web-security',
'--user-data-dir=/home/chrome-dir',
'--disable-features=CrossSiteDocumentBlockingIfIsolating'
My html page:
<html>
<body>
<iframe width="560" height="315" src="https://www.youtube.com></iframe>
</body>
</html>
Script that I'm injecting:
for (let i = 0; i < window.frames.length; i++) {
try {
const frame = window.frames[i];
console.log(frame.name, frame.document);
} catch (e) {
console.log(e);
}
}
My webdriver code:
const { Builder, Capabilities } = require('selenium-webdriver');
const fs = require('fs');
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
function constructChromeOptions() {
const options = {
'args': [
'--allow-file-access-from-files',
'--system-developer-mode',
'--force-dev-mode-highlighting',
'-–allow-file-access-from-files',
'--disable-web-security',
'--user-data-dir=/home/chrome-dir',
]
};
return options;
}
function constructChromeCapabilities(packedExtensionPath) {
const chromeCapabilities = Capabilities.chrome();
const chromeOptions = constructChromeOptions(packedExtensionPath);
const capabilities = chromeCapabilities.set('chromeOptions', chromeOptions);
return capabilities;
}
(async function init() {
let driver = await new Builder()
.withCapabilities(constructChromeCapabilities())
.forBrowser('chrome')
.build();
await driver.get(`file:///${__dirname}/iframes.html`);
const js = fs.readFileSync('scripts/inject.bundle.js', 'utf8');
driver.executeScript(js);
}();

Can't get the final frame content with puppeteer

Steps to reproduce
My environment:
Puppeteer version: 1.0.0
Platform / OS version: Linux / centos7.0
URLs (if applicable): http://1255.ijkuek.cn/
Node.js version: v9.4.0
What steps will reproduce the problem?
const puppeteer = require('puppeteer');
var args = process.argv.splice(2)
var url = args[0]
var ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0';
puppeteer.launch({
ignoreHTTPSErrors:true,
timeout: 1000,
args: ['--no-sandbox', '--disable-setuid-sandbox']}).then(async browser => {
const page = await browser.newPage();
await page.setExtraHTTPHeaders({
'upgrade-insecure-requests': '1'
});
page.setUserAgent(ua)
page.setDefaultNavigationTimeout(25000)
await page.setRequestInterception(true)
page.on('request', (request) => {
var type = request.resourceType()
if (type == 'image' || type == 'media')
request.abort();
else{
console.log("request: " + request.url())
request.continue();
}
});
page.on('response', (response) => {
console.log('response: ' + response.url())
if(type == 'document'){
response.text().then(function (textBody) {
console.log(textBody)
})
}
});
const response = await page.goto(url, {
waitUntil: 'networkidle2',
})
.catch(function(err){ if(err.toString().indexOf("Timeout")) {
browser.close();
console.log("Timeout!")
process.exit();
}})
browser.close();
});
What is the expected result?
the right redirect frame content
What happens instead?
the result is either timeout(to set timeout number larger useless )or redirect to wrong url,finally,can't get the final content。but phantomjs can get it!

How to use basic commands in webdriver.io

I'm using webdriver.io to do some browser automation. Not really testing , just saving time by automating things. I can see examples of how to use some of the functions .. but I can't seem to access them. I'm quite new to node.js
** Important ** I realise you can use browser.getAttribute - but looking at this example: http://webdriver.io/api/property/getAttribute.html
I should be able to execute getAttribute on the element object..?
var allInputs = $$('.loginForm input')
console.log(allInputs.map(function(el) { return el.getAttribute('name'); }))
My code:
var webdriverio = require('webdriverio');
var options = {
desiredCapabilities: {
browserName: 'chrome'
}
};
var browser = webdriverio.remote(options)
async function browserTest(){
await browser
.init()
.url('http://www.google.com')
.getTitle().then(function(title) {
console.log('Title was: ' + title);
})
.catch(function(err) {
console.log(err);
});
var body = await browser.element("//body")
console.log(body)
//the following line fails
console.log(await body.getAttribute("id"))
}
browserTest()

Proxy not changing to GET method

From within an app, I need to change a proxy to use the GET method to read data and not the OPTIONS method. I have attempted to set the 'method' for the proxy but it does not appear to be taking effect.
var operation = new Ext.data.Operation({
action: 'read',
});
var proxy = new Ext.data.proxy.Ajax({
type: 'ajax',
url: testURL,
method: 'GET',
withCredentials: true
});
proxy.read( operation );
Request Headers from debugger (notice OPTIONS)
OPTIONS /web/datasource?_dc=1476803593106&page=1&start=0&limit=25 HTTP/1.1
Host: <removed>
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: https://rally1.rallydev.com
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.59 Safari/537.36
Access-Control-Request-Headers: x-requested-with
Accept: */*
Referer: <hidden>
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8
The following code works but is not independent of a data store:
var createCORSRequest = function(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};
var url = testURL;
var method = 'GET';
var xhr = createCORSRequest(method, url);
xhr.onload = function() {
// Success code goes here.
alert( xhr.response );
};
xhr.onerror = function() {
// Error code goes here.
};
xhr.withCredentials = true;
xhr.send();

CasperJS test with PhantomJS webserver fails to load local image

I have a CasperJS test suite that needs to verify an image onload event. To test this I have a 1x1 pixel gif image, which I serve using PhantomJS webserver:
var fs = require('fs');
var webserver = require('webserver');
casper.test.begin('Image onload should be invoked', 1, {
setUp: function() {
var server = webserver.create();
this.server = server.listen(8080, function(request, response) {
if (request.url == '/') {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('' +
'<!doctype html>\n' +
'<html>\n' +
'<head>\n' +
'<script type="text/javascript">\n' +
'window.onload = function() {\n' +
'var px = document.createElement("img");\n' +
'px.onload = function() {\n' +
'window._pxLoad = true;\n' +
'};\n' +
'px.src = "px.gif";\n' +
'};\n' +
'</script>\n' +
'</head>\n' +
'<body></body>\n' +
'</html>' +
'');
} else if (request.url.match(/px\.gif$/i)) {
response.writeHead(200, {
'Content-Type': 'image/gif',
'Cache-Control': 'no-cache'
});
var filePath = fs.workingDirectory + request.url.split('/').join(fs.separator).replace(/\d/gi, '');
response.write(fs.read(filePath));
}
response.close();
});
},
tearDown: function() {
this.server.close();
},
test: function(test) {
casper.start('http://localhost:8080', function() {
this.waitFor(function() {
return this.evaluate(function () {
return window._pxLoad !== undefined;
});
}, function then() {
var flag = this.evaluate(function () {
return window._pxLoad;
});
test.assertTruthy(flag, 'Image has been successfully loaded');
});
});
casper.run(function () {
test.done();
});
}
});
This test fails because window._pxLoad !== undefined did not evaluate within the 5000ms timeout. I even placed console.log statements inside image handler and they showed that my routing works, server do receive this /px.gif call, but looks like git image isn't served at all.
I tried to replace the call to local px.gif with the similar image from the Internet, this one, and test passed! So the problem is definitely relates to how local gif image is served by PhantomJS webserver.
Ok, looks like I've found an answer by myself. Well, sort of.
First of all, I couldn't make my PhantomJS webserver solution work. So I created a simple Node.js script which runs a webserver. It is spawned as a child process before running test suite:
img_server.js
var http = require('http');
var fs = require('fs');
var path = require('path');
var argv = process.argv;
var port = argv.length > 3 ? parseInt(argv[3], 10) || 8124;
http.createServer(function(req, res) {
var fileStream = fs.createReadStream(path.join(__dirname, 'px.gif'));
res.writeHead(200, {
'Content-Type': 'image/gif',
'Cache-Control': 'no-cache'
});
fileStream.pipe(res);
}).listen(port);
// This is important. Script should put something in the STDOUT when started.
// The CasperJS test suite will bind to this inside setUp hook to know when server is ready
console.log('Server running at http://127.0.0.1:' + port + '/');
Changes to CasperJS test suite:
var fs = require('fs');
var webserver = require('webserver');
var process = require('child_process');
var spawn = process.spawn;
casper.test.setUp(function(done) {
this.imgServerChild = spawn('node', ['img_server.js', '-p', '8180']);
// This where STDOUT from server script is used
this.imgServerChild.stdout.on("data", done);
});
casper.test.tearDown(function() {
this.imgServerChild.kill('SIGKILL');
});
// The rest of test suite
Of course I also changed the path to the image file inside the faked HTML output. Now image is served from different domain, which is totally fine for me. Now tests are working.