Why did PhantomJS get two seconds slower for each Jasmine test?

Jasmine.configure do |config|
# Use whatever version of PhantomJS is already installed.
# Our Jasmine tests require PhantomJS 2.0+, which the
# phantomjs gem does not currently install.
config.prevent_phantom_js_auto_install = true
end

Knowledge is power

Jasmine doesn’t give us any running time information so it wasn’t clear exactly what was slow. To give us some visibility I created a slow spec reporter.

spec/javascripts/support/slow_reporter.js
config.show_console_log = true
// This test took ~15ms
it('has a <p> with the first line of content', () => {
expect(this.subject()).toHaveSelector('p', { text: '...' });
});
// This test took ~2000ms
it('has two <p>s', () => {
expect(this.subject()).toHaveSelector('p', { count: 2 });
});

A simple solution surfaces

This was repeatable in isolation, which told me that the problem was likely somewhere in our toHaveSelector custom matcher. Since the only difference between these examples was the type of options passed to the matcher, I looked for code differences in the matcher when using these different options and found this block:

if (options.count === undefined) {
// Check for element presence
result.pass = Utils.findElement(node, selector, options);
} else {
// Check the count of elements
result.pass =
Utils.countElement(node, selector, options) === options.count;
}
result.pass = !!Utils.findElement(node, selector, options);

--

--

Web infrastructure at @airbnb. Making web since the 90s. Co-created happo.io. he/him Minnesotan, liberal, dad. Follow @lencioni on Twitter.

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Joe Lencioni

Joe Lencioni

Web infrastructure at @airbnb. Making web since the 90s. Co-created happo.io. he/him Minnesotan, liberal, dad. Follow @lencioni on Twitter.