When comparing NW.js (w/xvfb) vs PhantomJS, the Slant community recommends PhantomJS for most people. In the question“What are the best headless browsers for testing?” PhantomJS is ranked 1st while NW.js (w/xvfb) is ranked 3rd.
Ranked in these QuestionsQuestion Ranking
Pro Node integration
The integration of Node with the DOM in NW.js opens up a number of new options in how your headless testing workflow can be facilitated.
Pro NaCl support/integration
Access to the Native Client offers up more options in implementing your testing workflow.
Pro Supports screen capture
Pro Used in many open source projects
Pro Supports many browser standards
PhantomJS has full DOM and CSS parsing, JSON, canvas, and SVG support.
Pro Built on WebKit
WebKit is becoming the gold standard for browser compatibility, making it a good starting point for native headless browser testing.
Con xvfb Requirement (for now)
Headless is on the NW.js roadmap, but for now xvfb is necessary to get going. The community has done the work and you can find the details here.
Con Deprecated by Puppeteer
PhantomJS is no longer actively maintained by the original authors. Puppeteer is said to be a replacement supported and backed by the Google Chrome team, now.
Con Heavy setup
You'll often end up having PhantomJS binaries connected via WebDriver to your testing framework, possibly using client/server especially if you want your test running with something else than Java. This means an overhead in terms of maintenance and performance, but still usually lighter than running a full browser (like Chrome, Firefox, IE).
Con Browser closes unexpectedly
It often happens when running on more then 5 (my measurement) JVM instances that the browser gets stuck and quits unexpectedly. This can be partially solved by running the instances one by one instead of parallel (this is a problem when testing Jenkins and Bamboo agents) but I don't believe this qualifies as a solution. The error is called
Con Elements are sometimes not visible
This is an error which occurs with almost no reason, PhantomJS sometimes decides that it cannot click the element even though the element is intractable or enabled.
The error it raises is: