Running React on PhantomJS

I ran into an issue getting a simple Capybara/Poltergeist feature test suite running against a site that used React.js. The following failure was bubbling up to RSpec.

Failures:

  1) customer accounts when the customer does not have an account registering
     Failure/Error: visit "/"
     Capybara::Poltergeist::JavascriptError:
       One or more errors were raised in the Javascript code on the page. If you don't care about these errors, you can ignore them by setting js_errors: false 
in your Poltergeist configuration (see documentation for details).

       TypeError: 'undefined' is not a function (evaluating 'RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/)')
       TypeError: 'undefined' is not a function (evaluating 'RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/)')
           at http://127.0.0.1:37189/assets/entries/cart.js:10341
           at http://127.0.0.1:37189/assets/entries/cart.js:21 in __webpack_require__
           at http://127.0.0.1:37189/assets/entries/cart.js:8445
           at http://127.0.0.1:37189/assets/entries/cart.js:8523
           at http://127.0.0.1:37189/assets/entries/cart.js:21 in __webpack_require__
           at http://127.0.0.1:37189/assets/entries/cart.js:134
           at http://127.0.0.1:37189/assets/entries/cart.js:209
           at http://127.0.0.1:37189/assets/entries/cart.js:21 in __webpack_require__
           at http://127.0.0.1:37189/assets/entries/cart.js:86
           at http://127.0.0.1:37189/assets/entries/cart.js:21 in __webpack_require__
           at http://127.0.0.1:37189/assets/entries/cart.js:66
           at http://127.0.0.1:37189/assets/entries/cart.js:21 in __webpack_require__
           at http://127.0.0.1:37189/assets/entries/cart.js:50
           at http://127.0.0.1:37189/assets/entries/cart.js:21 in __webpack_require__
           at http://127.0.0.1:37189/assets/entries/cart.js:41
           at http://127.0.0.1:37189/assets/entries/cart.js:19627
     # ./spec/features/account_spec.rb:47:in `block (3 levels) in <top (required)>'

Crisis

The undefined that wasn't a function here happens to be an ECMAScript 5.1 feature, Function.prototype.bind. This seemed a odd as that's supported by everything you care about if you're using React, and some digging showed that I wasn't the first to encounter this issue. PhantomJS uses a brutally old build of Webkit.

Accept Crime

This happens to be a feature that is easy to polyfill. MDN has a fine polyfill. Drop that into your project, and you're done. The polyfill solution isn't perfect, but it appears to be compatible with React. Just make sure to check the caveats on the polyfill if you're doing anything tricky or start running into strange problems.

Watch Out!

I've yet to run into any additional issues with PhantomJS's old Webkit build, but that doesn't mean they don't exist. I don't really know much about the state of support of ES5 in older versions Webkit, and I may need to get a proper ES5 shim if there are any other issues.