[
  {
    "path": ".editorconfig",
    "content": "# EditorConfig is awesome: http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\ninsert_final_newline = true\n\n# 4 space indentation\n[*.py]\nindent_style = space\nindent_size = 4\n\n# Tab indentation (no size specified)\n[*.js]\nindent_style = space\nindent_size = 4\n\n# Matches the exact files package.json and .travis.yml\n[{package.json,.travis.yml,Gruntfile.js}]\nindent_style = space\nindent_size = 2\n\n[Makefile]\nindent_style = tab\nindent_size = 4\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n- 4.2\n- 4.1\n- 0.12\n- 0.11\n- 0.10\nnotifications:\n  email:\n  - kimmo.brunfeldt+urltoimage@gmail.com\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\nAPI changes across versions\n\n## 0.2.0 -> 1.0.0\n\n* `.done` callback is now: `.then`\n\n    Promise library has been changed to [bluebird](http://bluebirdjs.com/docs/api-reference.html).\n\n* `.fail` callback is now: `.catch`\n\n* `options.ignoreSslErrors` was removed. Use `options.phantomArguments` instead.\n\n    Examples\n    ```\n    {\n        // Note: this is the new default for phantom arguments\n        phantomArguments: '--ignore-ssl-errors=true'\n    }\n    ```\n\n    ```\n    urltoimage --phantom-arguments=\"--ignore-ssl-errors=true\" google.com google.png\n    ```\n\n    See also: http://phantomjs.org/api/command-line.html\n\n* `options.sslProtocol` was removed. Use `options.phantomArguments` instead.\n\n    See above example.\n    See also: http://phantomjs.org/api/command-line.html\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Kimmo Brunfeldt\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# url-to-image\n\n**DEPRECATED:** I recommend using implementations that use Headless Chrome underneath, for example: https://github.com/kimmobrunfeldt/squint or https://github.com/alvarcarto/url-to-pdf-api. You can still continue using this module but no updates will be applied. \n\n\n[![Build Status](https://travis-ci.org/kimmobrunfeldt/url-to-image.png?branch=master)](https://travis-ci.org/kimmobrunfeldt/url-to-image)\n[![Dependency Status](https://david-dm.org/kimmobrunfeldt/url-to-image.png?theme=shields.io)](https://david-dm.org/kimmobrunfeldt/url-to-image)\n[![devDependency Status](https://david-dm.org/kimmobrunfeldt/url-to-image/dev-status.png?theme=shields.io)](https://david-dm.org/kimmobrunfeldt/url-to-image#info=devDependencies)\n\nTakes screenshot of a given page. This module correctly handles pages which dynamically load content making AJAX requests.\nInstead of waiting fixed amount of time before rendering, we give a short time for the page to make additional requests.\n\n**Usage from code:**\n\n```javascript\nconst urlToImage = require('url-to-image');\nurlToImage('http://google.com', 'google.png').then(function() {\n    // now google.png exists and contains screenshot of google.com\n}).catch(function(err) {\n    console.error(err);\n});\n```\n\n**Usage from command line:**\n\n```bash\n$ urltoimage http://google.com google.png\n```\n\nSometimes it's useful to see requests, responses and page errors from PhantomJS:\n\n```bash\n$ urltoimage http://google.com google.png --verbose\n-> GET http://google.com/\n-> GET http://www.google.fi/?gfe_rd=cr&ei=xTYxVouuOeiA8QexyZ2QBw\n<- 302 http://google.com/\n-> GET http://ssl.gstatic.com/gb/images/b_8d5afc09.png\n\n... quite a lot of requests ...\n\n-> GET http://ssl.gstatic.com/gb/js/sem_32d9c4210965b8e7bfa34fa376864ce8.js\n<- 200 http://ssl.gstatic.com/gb/js/sem_32d9c4210965b8e7bfa34fa376864ce8.js\nRender screenshot..\nDone.\n```\n\n\nFor more options, see [CLI](#command-line-interface-cli) chapter.\n\n## Install\n\n    npm install url-to-image\n\nPhantomJS is installed by using [Medium/phantomjs NPM module](https://github.com/Medium/phantomjs).\n\n## API\n\n```javascript\nconst urlToImage = require('url-to-image');\n```\n\n#### urlToImage(url, filePath, options)\n\nThis will run a PhantomJS script([url-to-image.js](./src/url-to-image.js)) which renders given url to an image.\n\n**Parameters**\n\n* `url` Url of the page which will be rendered as image. For example `http://google.com`.\n* `filePath` File path where to save rendered image.\n* `options` Options for page rendering.\n\n    **Default values for options**\n\n    ```javascript\n    {\n        // User agent width\n        width: 1200,\n\n        // User agent height\n        height: 800,\n\t\t\n\t\t// The file type of the rendered image. By default, PhantomJS \n\t\t// sets the output format automatically based on the file extension.\n\t\t// Supported: PNG, GIF, JPEG, PDF\n\t\tfileType: 'jpeg',\n\t\t\n\t\t// The file quality of the rendered image, represented as a percentage. \n\t\t// This reduces the image size. By default, 100 percent is used.\n\t\tfileQuality: 100,\n\t\t\n\t\t// Sets the width of the final image (cropped from the User agent defined size)\n\t\t// By default, no cropping is done.\n\t\tcropWidth: false,\n\t\t\n\t\t// Sets the height of the final image (cropped from the User agent defined size)\n\t\t// By default, no cropping is done.\n\t\tcropHeight: false,\n\t\t\n\t\t//Sets the offset of where to begin the image cropping from the left margin \n\t\t// of the page\n\t\tcropOffsetLeft: 0,\n\t\n    \t//Sets the offset of where to begin the image cropping from the top margin \n\t\t// of the page\n\t\tcropOffsetTop: 0,\n\n        // How long in ms do we wait for additional requests\n        // after all initial requests have gotten their response\n        // Note: this does NOT limit the amount of time individual request\n        //       can take in time\n        requestTimeout: 300,\n\n        // How long in ms do we wait at maximum. The screenshot is\n        // taken after this time even though resources are not loaded\n        maxTimeout: 1000 * 10,\n\n        // How long in ms do we wait for phantomjs process to finish.\n        // If the process is running after this time, it is killed.\n        killTimeout: 1000 * 60 * 2,\n\n        // If true, phantomjs script will output requests and responses to stdout\n        verbose: false,\n\n        // String of of phantomjs arguments\n        // You can separate arguments with spaces\n        // See options in http://phantomjs.org/api/command-line.html\n        phantomArguments: '--ignore-ssl-errors=true'\n    }\n    ```\n\n**Returns**\n\n[Bluebird promise object](http://bluebirdjs.com/docs/api-reference.html).\n\n**Detailed example**\n\n```javascript\nconst urlToImage = require('url-to-image');\n\nconst options = {\n    width: 600,\n    height: 800,\n    // Give a short time to load additional resources\n    requestTimeout: 100\n}\n\nurlToImage('http://google.com', 'google.png', options)\n.then(function() {\n    // do stuff with google.png\n})\n.catch(function(err) {\n    console.error(err);\n});\n```\n\n## Command line interface (CLI)\n\nThe package also ships with a cli called `urltoimage`.\n\n```\nUsage: urltoimage <url> <path> [options]\n\n<url>   Url to take screenshot of\n<path>  File path where the screenshot is saved\n\n\nOptions:\n  --width              Width of the viewport            [string] [default: 1280]\n  --height             Height of the viewport            [string] [default: 800]\n  --file-type          The file type of the rendered image. By default, \n\t\t               PhantomJS sets the output format automatically based on \n\t\t\t\t\t   the file extension. Supported: PNG, GIF, JPEG, PDF\n\t\t\t\t\t                                   [string] [default: false]\n  --file-quality       The file quality of the rendered image, represented as a \n                       percentage. This reduces the image size. \n\t\t\t\t\t   By default, 100 percent is used.\n\t\t\t\t\t                                     [string] [default: 100]\n  --crop-width         Sets the width of the final image (cropped from the User \n                       agent defined size).\n\t\t\t\t\t                                   [string] [default: false]\n  --crop-height        Sets the height of the final image (cropped from the User \n                       agent defined size).\n\t\t\t\t\t                                   [string] [default: false]\n  --cropoffset-left    Sets the offset of where to begin the image cropping from \n                       the left margin of the page.\n\t\t\t\t\t                                   [string] [default: false]\n  --cropoffset-top     Sets the offset of where to begin the image cropping from \n                       the top margin of the page.\n\t\t\t\t\t                                   [string] [default: false]\n  --request-timeout    How long in ms do we wait for additional requests after\n                       all initial requests have gotten their response\n                                                         [string] [default: 300]\n  --max-timeout        How long in ms do we wait at maximum. The screenshot is\n                       taken after this time even though resources are not\n                       loaded                          [string] [default: 10000]\n  --kill-timeout       How long in ms do we wait for phantomjs process to\n                       finish. If the process is running after this time, it is\n                       killed.                        [string] [default: 120000]\n  --phantom-arguments  Command line arguments to be passed to phantomjs\n                       process.You must use the format\n                       --phantom-arguments=\"--version\".\n                                  [string] [default: \"--ignore-ssl-errors=true\"]\n  --verbose            If set, script will output additional information to\n                       stdout.                        [boolean] [default: false]\n  -h, --help           Show help                                       [boolean]\n  -v, --version        Show version number                             [boolean]\n\nExamples:\n  urltoimage http://google.com google.png\n```\n\n# Contributors\n\n## Release\n\n* Commit all changes.\n* Use [releasor](https://github.com/kimmobrunfeldt/releasor) to automate the release:\n\n    `releasor --bump patch`\n\n* Edit GitHub release notes.\n\n## Test\n\n    npm test\n\n## Attribution\n\nThis module was inspired by\n\n* [url-to-screenshot](https://github.com/juliangruber/url-to-screenshot)\n* https://gist.github.com/cjoudrey/1341747\n\n# License\n\nMIT\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"url-to-image\",\n  \"version\": \"1.0.0\",\n  \"description\": \"PhantomJS screenshotting done right\",\n  \"main\": \"src/index.js\",\n  \"bin\": {\n    \"urltoimage\": \"./src/index.js\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git@github.com:kimmobrunfeldt/url-to-image.git\"\n  },\n  \"keywords\": [\n    \"phantomjs\",\n    \"screenshot\",\n    \"picture\",\n    \"webpage\",\n    \"render\"\n  ],\n  \"author\": \"Kimmo Brunfeldt\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/kimmobrunfeldt/url-to-image/issues\"\n  },\n  \"dependencies\": {\n    \"bluebird\": \"^3.5.0\",\n    \"lodash\": \"^4.17.4\",\n    \"phantomjs-prebuilt\": \"^2.1.7\",\n    \"yargs\": \"^8.0.2\"\n  },\n  \"devDependencies\": {\n    \"image-size\": \"^0.5.5\",\n    \"mocha\": \"^3.4.2\",\n    \"releasor\": \"^1.2.1\"\n  },\n  \"scripts\": {\n    \"test\": \"mocha\"\n  },\n  \"engines\": {\n    \"node\": \">=7.0\"\n  }\n}\n"
  },
  {
    "path": "src/cli-parser.js",
    "content": "'use strict';\n\nconst _ = require('lodash');\nconst yargs = require('yargs');\n\nconst VERSION = require('../package.json').version;\n\nconst defaultOpts = {\n    width: 1280,\n    height: 800,\n    requestTimeout: 300,\n    maxTimeout: 1000 * 10,\n    killTimeout: 1000 * 60 * 2,\n    verbose: false,\n    fileType: false,\n    fileQuality: false,\n    cropWidth: false,\n    cropHeight: false,\n    cropOffsetLeft: 0,\n    cropOffsetTop: 0,\n    phantomArguments: '--ignore-ssl-errors=true'\n};\n\nfunction getOpts(argv) {\n    const userOpts = getUserOpts();\n    const opts = _.merge(defaultOpts, userOpts);\n    return validateAndTransformOpts(opts);\n}\n\nfunction getUserOpts() {\n    const userOpts = yargs\n    .usage(\n        'Usage: $0 <url> <path> [options]\\n\\n' +\n        '<url>   Url to take screenshot of\\n' +\n        '<path>  File path where the screenshot is saved\\n'\n    )\n    .example('$0 http://google.com google.png')\n    .demand(2)\n    .option('width', {\n        describe: 'Width of the viewport',\n        default: defaultOpts.width,\n        type: 'string'\n    })\n    .option('height', {\n        describe: 'Height of the viewport',\n        default: defaultOpts.height,\n        type: 'string'\n    })\n    .option('request-timeout', {\n        describe: 'How long in ms do we wait for additional requests' +\n                  ' after all initial requests have gotten their response',\n        default: defaultOpts.requestTimeout,\n        type: 'string'\n    })\n    .option('max-timeout', {\n        describe: 'How long in ms do we wait at maximum. The screenshot is' +\n                  ' taken after this time even though resources are not loaded',\n        default: defaultOpts.maxTimeout,\n        type: 'string'\n    })\n    .option('file-type', {\n        describe: 'Defines the file type you want to create.',\n        default: defaultOpts.fileType,\n        type: 'string'\n    })\n    .option('file-quality', {\n        describe: 'Defines the quality of the file you want rendered' +\n        'as a percentage. Default is 100.',\n        default: defaultOpts.fileQuality,\n        type: 'string'\n    })\n    .option('crop-width', {\n        describe: 'The width of the final image which will be created',\n        default: defaultOpts.cropWidth,\n        type: 'string'\n    })\n    .option('crop-height', {\n        describe: 'The height of the final image which will be created',\n        default: defaultOpts.cropHeight,\n        type: 'string'\n    })\n    .option('cropoffset-left', {\n        describe: 'The position offset from the left of the screen from' +\n        ' where to start the image crop',\n        default: defaultOpts.cropOffsetLeft,\n        type: 'string'\n    })\n    .option('cropoffset-top', {\n        describe: 'The position offset from the top of the screen from' +\n        ' where to start the image crop',\n        default: defaultOpts.cropOffsetTop,\n        type: 'string'\n    })\n    .option('kill-timeout', {\n        describe: 'How long in ms do we wait for phantomjs process to finish.' +\n        ' If the process is running after this time, it is killed.',\n        default: defaultOpts.killTimeout,\n        type: 'string'\n    })\n    .option('phantom-arguments', {\n        describe: 'Command line arguments to be passed to phantomjs process.' +\n                  'You must use the format --phantom-arguments=\"--version\".',\n        default: defaultOpts.phantomArguments,\n        type: 'string'\n    })\n    .option('verbose', {\n        describe: 'If set, script will output additional information to stdout.',\n        default: defaultOpts.verbose,\n        type: 'boolean'\n    })\n    .help('h')\n    .alias('h', 'help')\n    .alias('v', 'version')\n    .version(VERSION)\n    .argv;\n\n    userOpts.url = userOpts._[0];\n    userOpts.path = userOpts._[1];\n    return userOpts;\n}\n\nfunction validateAndTransformOpts(opts) {\n    if (opts.width) {\n        validateNumber(opts.width, 'Incorrect argument, width is not a number');\n    }\n\n    if (opts.height) {\n        validateNumber(opts.height, 'Incorrect argument, height is not a number');\n    }\n\n    if (opts.requestTimeout) {\n        validateNumber(opts.requestTimeout, 'Incorrect argument, request timeout is not a number');\n    }\n\n    if (opts.maxTimeout) {\n        validateNumber(opts.maxTimeout, 'Incorrect argument, max timeout is not a number');\n    }\n\n    if (opts.killTimeout) {\n        validateNumber(opts.killTimeout, 'Incorrect argument, kill timeout is not a number');\n    }\n\n    if (opts.fileQuality) {\n        validateNumber(opts.fileQuality, 'Incorrect argument, file quality is not a number');\n    }\n\n    if (opts.cropWidth) {\n        validateNumber(opts.cropWidth, 'Incorrect argument, crop width is not a number');\n    }\n\n    if (opts.cropHeight) {\n        validateNumber(opts.cropHeight, 'Incorrect argument, crop height is not a number');\n    }\n\n    if (opts.cropOffsetLeft) {\n        validateNumber(opts.killTimeout, 'Incorrect argument, crop offset left is not a number');\n    }\n\n    if (opts.cropOffsetTop) {\n        validateNumber(opts.killTimeout, 'Incorrect argument, crop offset top is not a number');\n    }\n\n    return opts;\n}\n\nfunction validateNumber(val, message) {\n    const number = Number(val);\n    if (!_.isNumber(number)) {\n        const err = message;\n        err.argumentError = true;\n        throw err;\n    }\n}\n\nmodule.exports = {\n    defaultOpts: defaultOpts,\n    getOpts: getOpts\n};\n"
  },
  {
    "path": "src/index.js",
    "content": "#!/usr/bin/env node\n'use strict';\n\nconst Promise = require('bluebird');\nconst _ = require('lodash');\nconst path = require('path');\nconst childProcess = require('child_process');\nconst phantomjs = require('phantomjs')\nconst cliParser = require('./cli-parser');\n\nfunction render(url, filePath, opts) {\n    opts = _.extend(cliParser.defaultOpts, opts);\n\n    let args = [];\n    if (_.isString(opts.phantomArguments)) {\n        args = opts.phantomArguments.split(' ');\n    }\n\n    if (!_.startsWith(url, 'http') &&\n        !_.startsWith(url, 'https') &&\n        !_.startsWith(url, 'file')) {\n        url = 'http://' + url;\n    }\n\n    args = args.concat([\n        path.join(__dirname, 'url-to-image.js'),\n        url,\n        filePath,\n        opts.width,\n        opts.height,\n        opts.requestTimeout,\n        opts.maxTimeout,\n        opts.verbose,\n        opts.fileType,\n        opts.fileQuality,\n        opts.cropWidth,\n        opts.cropHeight,\n        opts.cropOffsetLeft,\n        opts.cropOffsetTop\n    ]);\n\n    let execOpts = {\n        maxBuffer: Infinity\n    };\n\n    let killTimer;\n    return new Promise(function(resolve, reject) {\n        let child;\n        killTimer = setTimeout(function() {\n            killPhantom(opts, child);\n            reject(new Error('Phantomjs process timeout'));\n        }, opts.killTimeout);\n\n        try {\n            child = childProcess.spawn(phantomjs.path, args, {\n                stdio: 'inherit'\n            });\n        } catch (err) {\n            return Promise.reject(err);\n        }\n\n        function errorHandler(err) {\n            // Remove bound handlers after use\n            child.removeListener('close', closeHandler);\n            reject(err);\n        }\n\n        function closeHandler(exitCode) {\n            child.removeListener('error', errorHandler);\n            if (exitCode > 0) {\n                let err;\n                if (exitCode === 10) {\n                    err = new Error('Unable to load given url: ' + url);\n                }\n                reject(err);\n            } else {\n                resolve(exitCode);\n            }\n        }\n\n        child.once('error', errorHandler);\n        child.once('close', closeHandler);\n    })\n    .finally(function() {\n        if (killTimer) {\n            clearTimeout(killTimer);\n        }\n    });\n}\n\nfunction killPhantom(opts, child) {\n    if (child) {\n        const msg = 'Phantomjs process didn\\'t finish in ' +\n                  opts.killTimeout + 'ms, killing it..';\n        console.error(msg);\n\n        child.kill();\n    }\n}\n\nif (require.main === module) {\n    let opts;\n    try {\n        opts = cliParser.getOpts();\n    } catch (err) {\n        if (err.argumentError) {\n            console.error(err.message);\n            process.exit(1);\n        }\n\n        throw err;\n    }\n\n    render(opts.url, opts.path, opts)\n    .catch(function(err) {\n        console.error('\\nTaking screenshot failed to error:');\n        if (err && err.message) {\n            console.error(err.message);\n        } else if (err) {\n            console.error(err);\n        } else {\n            console.error('No error message available');\n        }\n\n        process.exit(2);\n    });\n}\n\nmodule.exports = render;\n"
  },
  {
    "path": "src/url-to-image.js",
    "content": "'use strict';\n\n// PhantomJS script\n// Takes screeshot of a given page. This correctly handles pages which\n// dynamically load content making AJAX requests.\n\n// Instead of waiting fixed amount of time before rendering, we give a short\n// time for the page to make additional requests.\n\n// Phantom internals\nconst system = require('system');\nconst webPage = require('webpage');\n\nfunction main() {\n    // I tried to use yargs as a nicer commandline option parser but\n    // it doesn't run in phantomjs environment\n    const args = system.args;\n    const opts = {\n        url: args[1],\n        filePath: args[2],\n        width: args[3],\n        height: args[4],\n        requestTimeout: args[5],\n        maxTimeout: args[6],\n        verbose: args[7] === 'true',\n        fileType: args[8],\n        fileQuality: args[9] ? args[9] : 100,\n        cropWidth: args[10],\n        cropHeight: args[11],\n        cropOffsetLeft: args[12] ? args[12] : 0,\n        cropOffsetTop: args[13] ? args[13] : 0\n    };\n\n    renderPage(opts);\n}\n\nfunction renderPage(opts) {\n    let requestCount = 0;\n    let forceRenderTimeout;\n    let dynamicRenderTimeout;\n\n    const page = webPage.create();\n    page.viewportSize = {\n        width: opts.width,\n        height: opts.height\n    };\n    // Silence confirmation messages and errors\n    page.onConfirm = page.onPrompt = function noOp() {};\n    page.onError = function(err) {\n        log('Page error:', err);\n    };\n\n    page.onResourceRequested = function(request) {\n        log('->', request.method, request.url);\n        requestCount += 1;\n        clearTimeout(dynamicRenderTimeout);\n    };\n\n    page.onResourceReceived = function(response) {\n        if (!response.stage || response.stage === 'end') {\n            log('<-', response.status, response.url);\n            requestCount -= 1;\n            if (requestCount === 0) {\n                dynamicRenderTimeout = setTimeout(renderAndExit, opts.requestTimeout);\n            }\n        }\n    };\n\n    page.open(opts.url, function(status) {\n        if (status !== 'success') {\n            log('Unable to load url:', opts.url);\n            phantom.exit(10);\n        } else {\n            forceRenderTimeout = setTimeout(renderAndExit, opts.maxTimeout);\n        }\n    });\n\n    function log() {\n        // PhantomJS doesn't stringify objects very well, doing that manually\n        if (opts.verbose) {\n            let args = Array.prototype.slice.call(arguments);\n\n            let str = '';\n            args.forEach(function(arg) {\n                if (isString) {\n                    str += arg;\n                } else {\n                    str += JSON.stringify(arg, null, 2);\n                }\n\n                str += ' '\n            });\n\n            console.log(str);\n        }\n    }\n\n    function renderAndExit() {\n        log('Render screenshot..');\n        if(opts.cropWidth && opts.cropHeight) {\n        log(\"Cropping...\");\n            page.clipRect = {top: opts.cropOffsetTop, left: opts.cropOffsetLeft, width: opts.cropWidth, height: opts.cropHeight};\n        }\n\n        let renderOpts = {\n            fileQuality: opts.fileQuality\n        };\n\n        if(opts.fileType) {\n            log(\"Adjusting File Type...\");\n            renderOpts.fileType = opts.fileType;\n        }\n\n        page.render(opts.filePath, renderOpts);\n        log('Done.');\n        phantom.exit();\n    }\n}\n\nfunction isString(value) {\n    return typeof value === 'string'\n}\n\nmain();\n"
  },
  {
    "path": "test/test-functional.js",
    "content": "'use strict';\n\nconst http = require('http');\nconst fs = require('fs');\nconst assert = require('assert');\nconst sizeOf = require('image-size');\n\nconst urlToImage = require('../src/index');\n\ndescribe('urlToImage', function() {\n\n    const server = http.createServer(function(req, res) {\n        res.end('<html>test</html>');\n    });\n\n    before(function(done) {\n        server.listen(9000);\n        server.on('listening', done);\n    });\n\n    after(function(done) {\n        server.close();\n        done();\n    });\n\n    describe('render', function() {\n        this.timeout(20000);\n\n        it('should render test image', function(done) {\n            urlToImage('http://localhost:9000', 'localhost.png')\n            .then(function() {\n                const dimensions = sizeOf('localhost.png');\n                assert.equal(dimensions.width, 1280, 'default width is incorrect');\n                fs.unlinkSync('localhost.png');\n                done();\n            });\n        });\n\n        it('should render image in custom size', function(done) {\n            urlToImage(\n                'http://localhost:9000',\n                'localhost.png', {\n                    width: 800,\n                    height: 600\n                }\n            )\n            .then(function() {\n                const dimensions = sizeOf('localhost.png');\n\n                assert.equal(dimensions.width, 800, 'width is incorrect');\n\n                // The content of test page is so small, so viewport\n                // is larger than content. If content were larger,\n                // urlToImage's height could be bigger than viewport's width\n                assert.equal(dimensions.height, 600, 'height is incorrect');\n\n                fs.unlinkSync('localhost.png');\n                done();\n            });\n        });\n\n        it('should fail to incorrect url', function(done) {\n            this.timeout(5000);\n\n            urlToImage(\n                'http://failure',\n                'localhost.png', {\n                    width: 800,\n                    height: 600\n                }\n            )\n            .catch(function(err) {\n                done();\n            });\n        });\n    });\n});\n"
  }
]