Better Chrome browser history search using OmniHistoryPlus

An extension I used for years was called Fauxbar, which used an algorithm to create a much better (and fuller) experience when typing in a site you know you visited & want to return to.

Unfortunately, Fauxbar made extensive use of WebSQL, which was deprecated in newer versions of Chrome (hidden under a feature flag) and removed entirely from Chrome 123. It’s complex extension, and difficult to migrate to Manifest V3.. I had a brief try, but it was too much for me to tackle as a hobby project.

However, in some brief experiments with writing my first Chrome Extension, I found that the Chrome API is actually pretty good at searching your browse history (using chrome.history.search), and it’s really straight forward to present the results in the omnibar (using chrome.omnibox.onInputChanged).

This is when OmniHistoryPlus was born & is a great replacement for Fauxbar.

You activate it from the omnibar by typing ‘f’ followed by a tab or space, then you just search for a site you’ve visited; the results are more complete than you’d get from Chrome, and not muddied by web search results.

You can install the extension from the Chrome Web Store here.

And you’ll find the source code on GitHub here; https://github.com/mattcuk/OmniHistoryPlus

Give OmniHistoryPlus a try; you’ll find it’s a great alternative to Fauxbar, and gives you much better results than Chrome normally does!

Basic Automated Testing using FeatherTest for Chrome

There are a fair number of automated testing tools out there like Intern or Puppeteer, but I wanted something super simple and quick to set up to test a variety of pages on a site I develop.

I was making changes to JSON-LD, page metadata, and some of the data that’s sent to Omniture analytics. All the pages types are slightly different, containing things like Documents, Discussions, Blog Posts, landing pages, etc. So I needed to go to a variety of URLs on my local dev environment to see what certain DOM elements got set to, and check the contents of some JavaScript variables.

I’d then need to do the same checks against our Dev, Staging and Production servers to make sure they all looked correct there too.

After a bit of searching I came across FeatherTest which is fed a text file where you use JavaScript/jQuery to define & run the tests.

It’s very easy to set up tests, and the same test script file can be run against whatever site you’re looking at in your browser. For more info go here;

https://xaviesteve.com/5302/feathertest-automated-website-testing-extension-google-chrome/

Typical FeatherTest Script Structure + Syntax

Tip 1 – Preserve Log

The output from FeatherTest goes into the console, so if you’re testing multiple pages, you’ll need to check the ‘Preserve Log’ option, otherwise you’ll lose the output as Chrome navigates between pages.

Tip 2 – Output Formatting

When writing scripts, I’d recommend colouring the console output, and prefixing each line with something easily identifiable. In my case I’m using ‘SUDO – ‘ and colouring the text orange.

You can then simply filter the console to just see your output;

When you’ve filtered the output, you can then save it to a file (right-click, save as..) and format it into shape.

I’ve found this really useful to monitor how my SEO data has improved as I’ve made changes, and to sanity check I’ve not broken anything between releases.

Tip 3 – Variable access

Some of the test scripts I’ve written needed access to variables defined in the scope of the main window.. FeatherTest can’t normally access these variables, so we need a helper function.

The helper function either needs baking into your site’s JavaScript, or you can inject it using an extension like TamperMonkey. Using TamperMonkey means you can use it on whatever site you want, not just ones where you’re able to install the function on.

My code adds an event listener that you can call from FeatherTest which you can request variable values from.

e.g.

window.postMessage({ "action": "variable", "value": "myVar.hierarchy"}, window.origin);

This is the TamperMonkey/GreaseMonkey script I use;


// ==UserScript==
// @name FeatherTest Variable Support
// @namespace http://mysite
// @include http*://mysite/*
// @description Add support for FeatherTest variable access. Matt Collinge.
// @version 1.0
// @grant all
// ==/UserScript==
function featherTestSupport() {
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);
}
featherTestSupport();

FeatherTest Script – Example 1 – DOM Lookup

Pulling data out of the DOM is straightforward;


'feathertest'
console.log('%cSUDO – HOMEPAGE', 'color:orange');
location.href = '/site_root/'
60000
console.log('%cSUDO – '+location.href, 'color:orange');
console.log('%cSUDO – meta_title = '+$('meta[name="title"]').attr('content'), 'color:orange');
console.log('%cSUDO – meta_og:title = '+$('meta[property="og:title"]').attr('content'), 'color:orange');
console.log('%cSUDO – meta_description = '+$('meta[name="description"]').attr('content'), 'color:orange');
console.log('%cSUDO – meta_og:description = '+$('meta[property="og:description"]').attr('content'), 'color:orange');
console.log('%cSUDO – meta_og:image = '+$('meta[property="og:image"]').attr('content'), 'color:orange');
console.log('%cSUDO – meta_keywords = '+$('meta[name="keywords"]').attr('content'), 'color:orange');
console.log('%cSUDO – ', 'color:orange');

FeatherTest Script – Example 2 – Variable Access & JSON-LD

To access variables we’ll use the TamperMonkey function I posted above. We can also pull out any JSON-LD splats and present them quite nicely in the console output.


'feathertest'
console.log('%cSUDO – HOMEPAGE', 'color:orange');
location.href = '/site_root/'
60000
console.log('%cSUDO – '+location.href, 'color:orange');
// Output JSON-LD on page
$('script[type="application/ld+json"]').each(function(index,json){ console.log('%cSUDO – '+JSON.stringify(JSON.parse(json.innerHTML),null,2), 'color:orange') });
// Output the contents of some JavaScript variables
window.postMessage({ "action": "variable", "value": "myVar.hierarchy"}, window.origin);
window.postMessage({ "action": "variable", "value": "myVar.channel"}, window.origin);
window.postMessage({ "action": "variable", "value": "currentContainer.name"}, window.origin);
console.log('%cSUDO – ', 'color:orange');