luckyshot/feathertest

Accessing global variables doesn't work

Opened this issue · 0 comments

I've tried outputting global variables which are set during page load. These are accessible in Chrome Dev Tools like this;

window.myvariable

However, when I use the same variable in FeatherTest, it comes back as undefined, even when I'm confident that the line is executing after all the variables are set (I can see console log messages to that effect).

console.log(window.myvariable);

It seems to be due to 'window' being a stale (i.e. from the time the page started loading) copy which doesn't get updated as page ready scripts are executed.

I've worked around this on my own site by adding a message event listener like this;

if (typeof(window.addEventListener)!='undefined') window.addEventListener('message',function(event) {
	if(event.origin !== window.origin) return;
	// I could have used eval(), but that didn't feel secure enough to use in production
	var variableValue = event.data.split('.').reduce(function (object, property) {
		return object[property];
	}, window);
	
	console.log('%c'+event.data+' = '+variableValue, 'color:orange');
},false);

Which I can then call from FeatherTest like this;

window.postMessage('myvariable', window.origin)

So I can get around the problem by doing this on my own site, but it means I can't do it on other sites where this event listener isn't set up.

I've actually found that I can use TamperMonkey to add the event listener to whatever site I want. It uses unsafeWindow, which isn't ideal, but as long as you're aware of the risk and own the site you're doing this with, you should be fine.

// ==UserScript==
// @name        FeatherTest Variable Access
// @namespace   http://mysite
// @include     http*://mysite/*
// @description Add support for FeatherTest variable access. Matt Collinge.
// @version     1.0
// @grant all
// ==/UserScript==

function e14FeatherTestSupport() {
	if (typeof(window.addEventListener)!='undefined') window.addEventListener('message',function(event) {
		// Make sure the request is coming from our own site (or FeatherTest)
		if (event.origin !== window.origin) return;
		if (typeof(event.data.action)=='undefined') return;

		// Instead, I used this from StackOverflow; https://stackoverflow.com/questions/11924731/get-object-by-name-as-string-without-eval
		if (event.data.action=='variable') {
			var variableValue = event.data.value.split('.').reduce(function (object, property) {
				return object[property];
			}, unsafeWindow);

			console.log('%c'+event.data.value+' = '+variableValue, 'color:orange');
		}
	},false);
}

e14FeatherTestSupport();

Is there a better way to solve this within FeatherTest?

Thanks,

Matt.