I am trying to use Protractor for testing content scripts of a chrome extension. Chrome extension framework has a method for injecting a javascript file that you specify into the DOM and run it in a semi-isolated mode.
I want to simulate that by injecting the scripts myself into the DOM and then interacting with that JS and run some tests against the javascript that was inject.
So far I have figured out how to inject the javascript into the DOM. That part work but I can't seem to access the injected code in my tests. the variable dm which I set in the injected script is not accessible in the Protractor scope for some reason.
My tests:
describe('inject content script -', function () {
var contentScript;
beforeEach(function () {
browser.driver.ignoreSynchronization = true;
browser.driver.get('http://cnn.com');
browser.executeScript(function () {
//Script loading function
function load_script(urls) {
for (i = 0; i < urls.length; i++) {
var new_script = document.createElement('script');
new_script.type = 'text/javascript';
new_script.src = urls[i];
new_script.async = false;
new_script.defer = false;
document.getElementsByTagName('head')[0].appendChild(new_script);
console.log("injected " + urls[i]);
}
}
load_script([
"http://localhost:8000/bower_components/jquery/dist/jquery.min.js",
"http://localhost:8000/src/js/content-lib.js"
]);
console.log("finished injecting scripts");
// now attempting to wait until variable dm set by content script
// as global variable in DOM
function checkVariable() {
if (dm != undefined) {
return dm; // <= this is never reached because dm is always undefined.
}
else {
setTimeout(checkVariable(), 100);
}
}
console.log("wait for dm to be ready");
checkVariable();
}).then(function (dm) {
console.log("dm is ready");
console.log(dm);
contentScript = dm;
});
console.log("contentScript is ready");
console.log(contentScript);
});
it('basic content verication test', function () {
console.log(contentScript);
});
});
content-lib.js file:
dm = {};
dm.test=function (){
return "Hello world";
}
Some questions:
Will beforeEach() wait until all the injected scripts are loaded before execution is passed to it() call?
How can I interact with the code that was injected into a DOM dynamically.
Hi there!
Your question is better suited for StackOverflow or Gitter. Please ask a question there with the 'protractor' tag or post in the Gitter Channel to get help.
From the the getting help section of the README:
Please ask usage and debugging questions on StackOverflow (use the "protractor" tag) or in the Angular discussion group. (Please do not ask support questions here on Github.)
I solved the problem. This works in case someone else is looking for it.
beforeAll(function (done) {
browser.driver.ignoreSynchronization = true;
browser.driver.get('http://cnn.com');
browser.executeAsyncScript(function () {
var callback = arguments[arguments.length - 1];
//Script loading function
function load_script(urls) {
for (i = 0; i < urls.length; i++) {
var new_script = document.createElement('script');
new_script.type = 'text/javascript';
new_script.src = urls[i];
new_script.async = false;
new_script.defer = false;
document.getElementsByTagName('head')[0].appendChild(new_script);
console.log("injected " + urls[i]);
}
console.log("finished injecting scripts");
}
console.log("Before scripts");
load_script([
"http://localhost:8000/src/js/content-lib.js"
]);
setTimeout(function () {
callback(window.dm);
}, 2000);
}).then(function (dm) {
xm = dm;
done();
});
}, 10000); // wait 10 seconds to timeout the script injection
Most helpful comment
I solved the problem. This works in case someone else is looking for it.