Headless node.js javascript browser with screenshot capability? - javascript

Are there any headless browsers for node.js that support dumping a rendered page out to a file? I know phantomjs supports rendering to a file, but it doesn't run on node.js. I know zombie.js is a node.js headless browser, but it doesn't support rendering to a file.

I doubt you will find anything that is going to work as well as phantomjs. I would just treat the rendering as an async backend process and execute phantom in a subprocess from your main node.js process and call it a day. Rendering a web page is HARD, and since phantom is based on WebKit, it can actually do it. I don't think there will ever be a node library that can render a web page to a graphic file that isn't built upon an existing browser rendering engine. But maybe one day phantomjs will integrate more seamlessly with node.

Try nightmare, it uses the electron, it is way faster than phantomjs, and it's API easy and uses modern ES6 javascript.

This might look like a solution with a little bit overhead...
You can use the Mozilla Firefox with the MozRepl plugin. Basically this plugin gives you a telnet port to your Firefox which allows you to control the browser from the outside. You can open URLs, take screenshots, etc.
Running the Firefox with the Xvfb server will run it in headless mode.
Now you just have to control the browser from the outside with node.js. I've seen a few examples where someone has implemented a http alike interface inside the chrome.js of Firefox. So you can run a http command to get a screenshot. You can then use http calls from node.js. This might look strange, it actually is but might work well for you.
http://hyperstruct.net/2009/02/05/turning-firefox-into-a-screenshot-server-with-mozrepl/
I'm running a slightly modified version in production with Perl Mojolicious in async mode to trigger the screenshots. However, there is a small problem. When plugins are required they do work, however Flash usually gets activated when it's in the visible area, this won't happen so movies/flash things might not get initialized.

You might find this helpful, though it's not javascript specific.
There is a webkit-based tool called "wkhtmltopdf" that I understand includes javascript support using the QT web-kit widget. It outputs a visual representation ("screenshot" if you will) of the page in PDF format.
FWIW, there are also PHP bindings for it here: php-wkthmltox

The Chrome dev team has released Puppeteer which can be used in node. It uses Chrome with the headless option.

There's a project called Node-Chimera. Although it's not as mature as Phantomjs, it has all the features you have mentioned: it runs on native Nodejs, and allows you to render pages to a file. Repository is here: https://github.com/deanmao/node-chimera. It has examples to do exactly what you need.

Related

Injecting a JavaScript script using Selenium Driver + PhantomJS and handling the redirection correctly in Python

My problem is:
I have being developing a Python script that connects to an URL, and using the selenium driver I manage to inject a Javascript file, after this file executes the currently page is redirected. This's all done using selenium to handle Firefox:
driver = webdriver.Firefox();
, but when I try to use PhantomJS as the browser, since it doesn't have any graphical interface:
driver = webdriver.PhantomJS();
I can't handle the response properly. Still haven't found out if the driver is not injecting the script correctly or if it's an response handling problem. If someone has any ideas it'll be great to hear.
I posted this on another question, but I think this will help:
After dealing with this same dilemma myself, I can wholeheartedly recommend using your preferred Selenium webkit (mine is Chrome) in conjunction with XVFB.
XVFB allows you to heedlessly run a browser like Firefox, Chrome, etc. which basically eradicates all of the bugginess that inherently comes with using PhantomJS. While it’s definitely an awesome piece, it’s inner workings tend to have different interactions at times (I ran into issues for instance with not being able to TAB from one element to another like one can in any browser). If you are using Jenkins, there is an incredibly awesome Plugin which literally takes one click of a button. Otherwise, I’d definitely recommend checking this out.
Phantom is a real pain in the ass, so it's definitely worth circumventing it :)
Hope this helps!

Is there a way to automate the testing of chrome extensions? [duplicate]

I'm going to write bunch of browser extensions (the same functionality for each popular browser). I hope, that some of the code will be shared, but I'm not sure about this yet. For sure some of extensions will use native API. I have not much experience with TDD/BDD, and I thought it's good time to start folowing these ideas from this project.
The problem is, I have no idea how to handle it. Should I write different tests for each browser? How far should I go with these tests? These extensions will be quite simple - some data in a local storage, refreshing a page and listening through web sockets.
And my observation about why is it hard for me - because there is a lot of behaviour, and not so much models, which are also dependent on a platform.
I practise two different ways of testing my browser extensions:
Unit tests
Integration test
Introduction
I will use the cross-browser YouTube Lyrics by Rob W extension as an example throughout this answer. The core of this extension is written in JavaScript and organized with AMD modules. A build script generates the extension files for each browser. With r.js, I streamline the inclusion of browser-specific modules, such as the one for cross-origin HTTP requests and persistent storage (for preferences), and a module with tons of polyfills for IE.
The extension inserts a panel with lyrics for the currently played song on YouTube, Grooveshark and Spotify. I have no control over these third-party sites, so I need an automated way to verify that the extension still works well.
Workflow
During development:
Implement / edit feature, and write a unit test if the feature is not trivial.
Run all unit tests to see if anything broke. If anything is wrong, go back to 1.
Commit to git.
Before release:
Run all unit tests to verify that the individual modules is still working.
Run all integration tests to verify that the extension as whole is still working.
Bump versions, build extensions.
Upload update to the official extension galleries and my website (Safari and IE extensions have to be hosted by yourself) and commit to git.
Unit testing
I use mocha + expect.js to write tests. I don't test every method for each module, just the ones that matter. For instance:
The DOM parsing method. Most DOM parsing methods in the wild (including jQuery) are flawed: Any external resources are loaded and JavaScript is executed.
I verify that the DOM parsing method correctly parses DOM without negative side effects.
The preference module: I verify that data can be saved and returned.
My extension fetches lyrics from external sources. These sources are defined in separate modules. These definitions are recognized and used by the InfoProvider module, which takes a query, (black box), and outputs the search results.
First I test whether the InfoProvider module functions correctly.
Then, for each of the 17 sources, I pass a pre-defined query to the source (with InfoProvider) and verify that the results are expected:
The query succeeds
The returned song title matches (by applying a word similarity algorithm)
The length of the returned lyrics fall inside the expected range.
Whether the UI is not obviously broken, e.g. by clicking on the Close button.
These tests can be run directly from a local server, or within a browser extension. The advantage of the local server is that you can edit the test and refresh the browser to see the results. If all of these tests pass, I run the tests from the browser extension.
By passing an extra parameter debug to my build script, the unit tests are bundled with my extension.
Running the tests within a web page is not sufficient, because the extension's environment may differ from the normal page. For instance, in an Opera 12 extension, there's no global location object.
Remark: I don't include the tests in the release build. Most users don't take the efforts to report and investigate bugs, they will just give a low rating and say something like "Doesn't work". Make sure that your extension functions without obvious bugs before shipping it.
Summary
View modules as black boxes. You don't care what's inside, as long as the output matches is expected or a given input.
Start with testing the critical parts of your extension.
Make sure that the tests can be build and run easily, possibly in a non-extension environment.
Don't forget to run the tests within the extension's execution context, to ensure that there's no constraint or unexpected condition inside the extension's context which break your code.
Integration testing
I use Selenium 2 to test whether my extension still works on YouTube, Grooveshark (3x) and Spotify.
Initially, I just used the Selenium IDE to record tests and see if it worked. That went well, until I needed more flexibility: I wanted to conditionally run a test depending on whether the test account was logged in or not. That's not possible with the default Selenium IDE (it's said to be possible with the FlowControl plugin - I haven't tried).
The Selenium IDE offers an option to export the existing tests in other formats, including JUnit 4 tests (Java). Unfortunately, this result wasn't satisfying. Many commands were not recognized.
So, I abandoned the Selenium IDE, and switched to Selenium.
Note that when you search for "Selenium", you will find information about Selenium RC (Selenium 1) and Selenium WebDriver (Selenium 2). The first is the old and deprecated, the latter (Selenium WebDriver) should be used for new projects.
Once you discovered how the documentation works, it's quite easy to use.
I prefer the documentation at the project page, because it's generally concise (the wiki) and complete (the Java docs).
If you want to get started quickly, read the Getting Started wiki page. If you've got spare time, look through the documentation at SeleniumHQ, in particular the Selenium WebDriver and WebDriver: Advanced Usage.
Selenium Grid is also worth reading. This feature allows you to distribute tests across different (virtual) machines. Great if you want to test your extension in IE8, 9 and 10, simultaneously (to run multiple versions of Internet Explorer, you need virtualization).
Automating tests is nice. What's more nice? Automating installation of extensions!
The ChromeDriver and FirefoxDriver support the installation of extensions, as seen in this example.
For the SafariDriver, I've written two classes to install a custom Safari extension. I've published it and sent in a PR to Selenium, so it might be available to everyone in the future: https://github.com/SeleniumHQ/selenium/pull/87
The OperaDriver does not support installation of custom extensions (technically, it should be possible though).
Note that with the advent of Chromium-powered Opera, the old OperaDriver doesn't work any more.
There's an Internet Explorer Driver, and this one does definitely not allow one to install a custom extension. Internet Explorer doesn't have built-in support for extensions. Extensions are installed through MSI or EXE installers, which are not even integrated in Internet Explorer. So, in order to automatically install your extension in IE, you need to be able to silently run an installer which installs your IE plugin. I haven't tried this yet.
Testing browser extensions posed some difficulty for me as well, but I've settled on implementing tests in a few different areas that I can invoke simultaneously from browsers driven by Selenium.
The steps I use are:
First, I write test code integrated into the extension code that can be activated by simply going to a specific URL. When the extension sees that URL, it begins running the tests.
Then, in the page that activates the testing in the extension I execute server-side tests to be sure the API performs, and record and log issues there. I record the methods invoked, the time they took, and any errors. So I can see the method the extension invoked, the web performance, the business logic performance, and the database performance.
Lastly, I automatically invoke browsers to point at that specific URL and record their performance along with other test information, errors, etc on any given client system using Selenium:
http://docs.seleniumhq.org/
This way I can break down the tests in terms of browser, extension, server, application, and database and link them all together according to specific test sets. It takes a bit of work to put it all together, but once its done you can have a very nice extension testing framework.
Typically for cross-browser extension development in order to maintain a single code-base I use crossrider, but you can do this with any framework or with native extensions as you wish, Selenium won't care, it is just driving the extension to a particular page and allowing you to interact and perform tests.
One nice thing about this approach is you can use it for live users as well. If you are providing support for your extension, have a user go to your test url and immediately you will see the extension and server-side performance. You won't get the Selenium tests of course, but you will capture a lot of issues this way - very useful when you are coding against a variety of browsers and browser versions.

Javascript unit testing with V8

Currently, I am using PhantomJS for running Javascript unit tests in QUnit and Sinon framework on our build server.
But, PhantomJS uses JavaScriptCore with JIT compiler as its Javascript engine. Instead, I want to use the V8 engine, which is used in Google Chrome, or Chakra, which is used in IE. I want to do this because I want to check platform compatibility for the code.
Are there any popular test runners like PhantomJS, which use these engines?
The closest I can think of is Zombie.js, which is a headless browser written in Javascript that runs under Node.js.
It's not a genuine browser in the way that Phantom is, so there are things you won't be able to do with it that you can do with Phantom, but since it uses Node.js, it obviously does use the V8 engine, so it fulfils your criteria.
But if you really want to test in all the browser's various engines, your other option is, of course, to use a real browser. You don't have to have a visible UI for it; use a tool like Selenium or Sahi, which can launch and run the browser from a script, and have it run in a VM; you don't ever need to even look at it. It may not be as quick as using Phantom, but it will be a genuine test, which is clearly what you're really interested in.
[EDIT]
Worth adding a note to this answer because I recently found out about SlimerJS, which is an open source project aiming to produce a PhantomJS-compatible browser that uses the Gecko engine. Again, this isn't exactly what was asked for in the question, but it is in the spirit of it; it's great to have another tool available to make cross-platform testing easier.

Web Automation Tool

I've realized I need a full-fledged browser automation tool for testing user interactions with our JavaScript widget library. I was using qunit, starting with unit testing and then I unwisely started incorporating more and more functional tests. That was a bad idea: trying to simulate a lot of user actions with JavaScript. The timing issues have gotten out of control and have made the suite too brittle. Now I spend more time fixing the tests, then I do developing.
Is it possible to find a browser automation tool that works in:
Windows XP: IE6,7,8, FF3
OSX: Safari, FF3
?
I've looked into SeleniumIDE and RC, but there seems to be some IE8 problems.
I've also seen some things about Google's WebDriver, which confusingly seems to work with Selenium.
Our organziation has licenses for IBM's Rational Functional Tester, but I don' think that will work on the MAC.
The idea is to try to run tests on all the browsers our organization supports. Doable? Are my requirements unrealistic? Any recommendations as far as software to try?
Thanks!
I would recommend using Selenium but I say that as a Selenium Committer.
Selenium works on any browser that supports JavaScript since the framework has been written in JavaScript. This means if your browser on any OS supports JavaScript it will run in Selenium. That documentation it out of date, you can see that since it is talking about IE8b1 and IE9 preview is out now.
Selenium and WebDriver (which isn't a Google thing since it started at ThoughtWorks) are currently being merged as they both have their strengths and weaknesses. The current merged work will be called Selenium 2 and you can start using the alpha release now at http://code.google.com/p/selenium/. It will still work on any OS as that is still the main driving force behind the work being done.
Selenium IDE only works on Firefox because it is a Firefox add on.
I personally would avoid Rational Functional Tester because it has a lot of weaknesses that its not even worth contemplating.
If you start with Selenium there are some tutorials on my site at http://www.theautomatedtester.co.uk
Try Sahi (http://sahi.co.in/) It works across browsers and operating systems. It has a powerful recorder, and great APIs for object identification. It supports HTTPS, proxy tunneling etc. and has drivers in sahi script, java and ruby. It also has parallel playback inbuilt. It is 5 yr old mature project hosted on SourceForge, with releases almost every month.
It automatically waits for AJAX and page loads, and does not use XPaths for object identification. It also handles sites with dynamic ids.
Selenium is probably your best bet out of the tools you mentioned. What are the issues it has with IE8? You might want to check out HttpUnit to see if that meets your needs, also.
Selenium RC is a great tool if you invest the time to use it. With significant modifications to the existing library I've gotten it to fulfill all of my front end testing needs.
The confusion you are having about Webdriver is understandable. Selenium 2 is in development and will be a merge of Webdriver and Selenium. Check out: http://www.youtube.com/watch?v=RQD4EzWI4qk to get more detail.
The only browser that I have found to be unusable with Selenium is IE6. IE7 and IE8 work fine as does Firefox (which I have modified to include firebug for debugging purposes).
I'm in the same boat. It is a difficult problem to solve. Windmill and Selenium are the 2 best I've found. Though they both have issues. Selenium can only record scripts in Firefox and I haven't managed to get the proxy chaining to work as advertised. Windmill you can record in any browser and you can supposedly tweak the proxy to put extra logic in there, but the js mechanism for recording across page loads has been in my experience very brittle at least on the app I have to test.
I don't think anyone can get it quite right as long as there is more than one browser that needs to be supported.
Maybe have a look at SIKULI. It's a different paradigm but, depending on what you want to test exactly, it may do the job and will work with any browser, on any platform.
Have a look at their official blog for some examples of interactions with web applications.
So I wrote some of my more problematic tests in Selenium RC, using the Python driver. It was a better experience than writing the same tests in pure JavaScript, but I still had some of the same issues.
Testing something like an ajax autocomplete widget, meant forking some of the code depending on IE, or Firefox, and I still can't get typeKeys or a combination of type with typeKeys to work in Safari.
So, I am not sure if having cross browser clean, extensive ui tests is a bit unrealistic.
Should I try webdriver/Selenium 2? Would that make things better, or is that product not ready for prime time yet? How's the Python binding for that? I don't know Java, but I would learn some if need be.

Can you use the JavaScript engine in web browsers to process local files?

I have a number of users with multi-megabyte files that need to be processed before they can be uploaded. I am trying to find a way to do this without having to install any executable software on their machines.
If every machine shipped with, say, Python it would be easy. I could have a Python script do everything. The only scripting language I can think of that's on every machine is JavaScript. However I know there are security restrictions that prevent reading and writing local files from web browsers.
Is there any way to use this extremely pervasive scripting language for general purpose computing tasks?
EDIT: To clarify the requirements, this needs to be a cross platform, cross browser solution. I believe that HTA is an Internet Explorer only technology (or that the Firefox equivalent is broken).
Would Google Gears work here? Yes, users have to install something, but I think the experience is fairly frictionless. And once it's installed, no more worries.
The application that I maintain and develop for work is an HTML Application or HTA, linked with a SQL Server 2005 backend. This allows various security restrictions to be "avoided". All the client-side components in the application are done with javascript, including writing files to locally mapped network drives and loading data into screens/pages in an AJAXy way.
Perhaps HTA could be helpful for your situation.
For an example of javascript accessing a local file, you might try taking a look at the source of TiddlyWiki, specifically the saveFile, mozillaSaveFile, and ieSaveFile functions. Just click the download link, open the html file it sends you, and search for those functions.
Of course, tiddlywiki is supposed to be used as a local file, not served over the web, so the methods it uses may only work locally.. But it might be a start.
Why not use a flash uploader? http://swfupload.org/
Adobe Flex 4 lets you to open and process a file on a local machine:
http://livedocs.adobe.com/flex/3/langref/flash/net/FileReference.html#load()
It's not exactly JavaScript, but hope that helps.
I believe you can accomplish this using the HTML5 File API.
It is supported in Opera, IE, Safari, Firefox, and Chrome.
you can use fs module from nodeJS to manipulate with filesystem nowadays!

Categories